Skip to content

Commit d981352

Browse files
authored
Add Hunt captcha support with tests and examples (#142)
1 parent 10a275f commit d981352

10 files changed

Lines changed: 281 additions & 1 deletion

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Examples of API requests for different captcha types are available on the [Pytho
5151
- [Altcha Captcha](#altcha-Captcha)
5252
- [Binance](#binance)
5353
- [Yidun](#yidun)
54+
- [Hunt](#hunt)
5455
- [Other methods](#other-methods)
5556
- [send / get\_result](#send--get_result)
5657
- [balance](#balance)
@@ -560,6 +561,17 @@ result = solver.yidun(sitekey='6b4d7e0c4f5a4c7db2f3a1e8c9d6f123',
560561
)
561562
```
562563

564+
### Hunt
565+
566+
<sup>[API method description.](https://2captcha.com/2captcha-api#hunt)</sup>
567+
568+
Use this method to solve Hunt captcha. Returns a token.
569+
```python
570+
result = solver.hunt(pageurl='https://example.com/page-with-hunt',
571+
api_get_lib='https://example.com/hd-api/external/apps/app-id/api.js',
572+
)
573+
```
574+
563575
## Other methods
564576

565577
### send / get_result

examples/async/async_hunt.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import asyncio
2+
import sys
3+
import os
4+
5+
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
6+
7+
from twocaptcha import AsyncTwoCaptcha
8+
9+
# in this example we store the API key inside environment variables that can be set like:
10+
# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS
11+
# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows
12+
# you can just set the API key directly to it's value like:
13+
# api_key="1abc234de56fab7c89012d34e56fa7b8"
14+
15+
api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY')
16+
17+
solver = AsyncTwoCaptcha(api_key)
18+
19+
async def solve_captcha():
20+
try:
21+
return await solver.hunt(
22+
pageurl='https://example.com/page-with-hunt',
23+
api_get_lib='https://example.com/hd-api/external/apps/app-id/api.js',
24+
)
25+
26+
except Exception as e:
27+
sys.exit(e)
28+
29+
if __name__ == '__main__':
30+
result = asyncio.run(solve_captcha())
31+
sys.exit('result: ' + str(result))
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import asyncio
2+
import sys
3+
import os
4+
5+
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
6+
7+
from twocaptcha import AsyncTwoCaptcha
8+
9+
# in this example we store the API key inside environment variables that can be set like:
10+
# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS
11+
# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows
12+
# you can just set the API key directly to it's value like:
13+
# api_key="1abc234de56fab7c89012d34e56fa7b8"
14+
15+
api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY')
16+
17+
config = {
18+
'server': '2captcha.com', # can be also set to 'rucaptcha.com'
19+
'apiKey': api_key,
20+
'softId': 123,
21+
'defaultTimeout': 120,
22+
'recaptchaTimeout': 600,
23+
'pollingInterval': 10,
24+
}
25+
26+
solver = AsyncTwoCaptcha(**config)
27+
28+
async def solve_captcha():
29+
try:
30+
return await solver.hunt(
31+
pageurl='https://example.com/page-with-hunt',
32+
api_get_lib='https://example.com/hd-api/external/apps/app-id/api.js',
33+
data='META_TOKEN_VALUE',
34+
useragent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
35+
# proxy={'type': 'HTTP',
36+
# 'uri': 'login:password@IP_address:PORT'}
37+
)
38+
except Exception as e:
39+
sys.exit(e)
40+
41+
if __name__ == '__main__':
42+
result = asyncio.run(solve_captcha())
43+
sys.exit('result: ' + str(result))

examples/sync/hunt.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import sys
2+
import os
3+
4+
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
5+
6+
from twocaptcha import TwoCaptcha
7+
8+
# in this example we store the API key inside environment variables that can be set like:
9+
# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS
10+
# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows
11+
# you can just set the API key directly to it's value like:
12+
# api_key="1abc234de56fab7c89012d34e56fa7b8"
13+
14+
api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY')
15+
16+
solver = TwoCaptcha(api_key)
17+
18+
try:
19+
result = solver.hunt(
20+
pageurl='https://example.com/page-with-hunt',
21+
api_get_lib='https://example.com/hd-api/external/apps/app-id/api.js',
22+
)
23+
24+
except Exception as e:
25+
sys.exit(e)
26+
27+
else:
28+
sys.exit('result: ' + str(result))

examples/sync/hunt_options.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import sys
2+
import os
3+
4+
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
5+
6+
from twocaptcha import TwoCaptcha
7+
8+
# in this example we store the API key inside environment variables that can be set like:
9+
# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS
10+
# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows
11+
# you can just set the API key directly to it's value like:
12+
# api_key="1abc234de56fab7c89012d34e56fa7b8"
13+
14+
api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY')
15+
16+
config = {
17+
'server': '2captcha.com', # can be also set to 'rucaptcha.com'
18+
'apiKey': api_key,
19+
'softId': 123,
20+
'defaultTimeout': 120,
21+
'recaptchaTimeout': 600,
22+
'pollingInterval': 10,
23+
}
24+
25+
solver = TwoCaptcha(**config)
26+
27+
try:
28+
result = solver.hunt(
29+
pageurl='https://example.com/page-with-hunt',
30+
api_get_lib='https://example.com/hd-api/external/apps/app-id/api.js',
31+
data='META_TOKEN_VALUE',
32+
useragent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
33+
# proxy={'type': 'HTTP',
34+
# 'uri': 'login:password@IP_address:PORT'}
35+
)
36+
37+
except Exception as e:
38+
sys.exit(e)
39+
40+
else:
41+
sys.exit('result: ' + str(result))

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ def get_version():
3636
'2captcha', 'captcha', 'api', 'captcha solver', 'reCAPTCHA',
3737
'FunCaptcha', 'Geetest', 'image captcha', 'Coordinates', 'Click Captcha',
3838
'Geetest V4', 'Lemin captcha', 'Amazon WAF', 'Cloudflare Turnstile',
39-
'Capy Puzzle', 'MTCaptcha', 'Friendly Captcha', 'Tencent', 'Cutcaptcha', 'DataDome', 'VK Captcha', 'CaptchaFox', 'Prosopo', 'cybersiara'],
39+
'Capy Puzzle', 'MTCaptcha', 'Friendly Captcha', 'Tencent', 'Cutcaptcha', 'DataDome', 'VK Captcha', 'CaptchaFox', 'Prosopo', 'cybersiara', 'Hunt'],
4040
python_requires='>=3.8',
4141
test_suite='tests')

tests/async/test_async_hunt.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python3
2+
3+
import unittest
4+
5+
try:
6+
from .abstract_async import AsyncAbstractTest
7+
except ImportError:
8+
from abstract_async import AsyncAbstractTest
9+
10+
11+
class AsyncHunt(AsyncAbstractTest):
12+
def test_all_params(self):
13+
params = {
14+
'pageurl': 'https://example.com/page-with-hunt',
15+
'api_get_lib': 'https://example.com/hd-api/external/apps/app-id/api.js',
16+
'data': 'META_TOKEN_VALUE',
17+
'useragent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
18+
'proxy': {'type': 'HTTP',
19+
'uri': 'login:password@IP_address:PORT'}
20+
}
21+
22+
sends = {
23+
'method': 'hunt',
24+
'pageurl': 'https://example.com/page-with-hunt',
25+
'api_get_lib': 'https://example.com/hd-api/external/apps/app-id/api.js',
26+
'data': 'META_TOKEN_VALUE',
27+
'useragent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
28+
'proxytype': 'HTTP',
29+
'proxy': 'login:password@IP_address:PORT'
30+
}
31+
32+
self.send_return(sends, self.solver.hunt, **params)
33+
34+
35+
if __name__ == '__main__':
36+
unittest.main()

tests/sync/test_hunt.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env python3
2+
3+
import unittest
4+
5+
try:
6+
from .abstract import AbstractTest
7+
except ImportError:
8+
from abstract import AbstractTest
9+
10+
11+
class CaptchaHunt(AbstractTest):
12+
13+
def test_all_params(self):
14+
params = {
15+
'pageurl': 'https://example.com/page-with-hunt',
16+
'api_get_lib': 'https://example.com/hd-api/external/apps/app-id/api.js',
17+
'data': 'META_TOKEN_VALUE',
18+
'useragent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
19+
'proxy': {'type': 'HTTP',
20+
'uri': 'login:password@IP_address:PORT'}
21+
}
22+
23+
sends = {
24+
'method': 'hunt',
25+
'pageurl': 'https://example.com/page-with-hunt',
26+
'api_get_lib': 'https://example.com/hd-api/external/apps/app-id/api.js',
27+
'data': 'META_TOKEN_VALUE',
28+
'useragent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
29+
'proxytype': 'HTTP',
30+
'proxy': 'login:password@IP_address:PORT'
31+
}
32+
33+
return self.send_return(sends, self.solver.hunt, **params)
34+
35+
36+
if __name__ == '__main__':
37+
unittest.main()

twocaptcha/async_solver.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,31 @@ async def yidun(self, sitekey, pageurl, **kwargs):
10771077

10781078
return await result
10791079

1080+
async def hunt(self, pageurl, api_get_lib, **kwargs):
1081+
'''Wrapper for solving Hunt captcha.
1082+
1083+
Parameters
1084+
__________
1085+
pageurl : str
1086+
Full URL of the page with the captcha.
1087+
api_get_lib : str
1088+
Full link to the api.js file that loads the captcha on the page.
1089+
data : str, optional
1090+
Value of `meta.token` that the site returned after a request with X-HD.
1091+
Use only for the captcha solving mode (second step).
1092+
useragent : str, optional
1093+
Browser User-Agent used to open the page.
1094+
proxy : dict, optional
1095+
{'type': 'HTTPS', 'uri': 'login:password@IP_address:PORT'}.
1096+
'''
1097+
result = self.solve(
1098+
method="hunt",
1099+
pageurl=pageurl,
1100+
api_get_lib=api_get_lib,
1101+
**kwargs)
1102+
1103+
return await result
1104+
10801105
async def solve(self, timeout=0, polling_interval=0, **kwargs):
10811106
'''Sends captcha, receives result.
10821107

twocaptcha/solver.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class TwoCaptcha():
113113
Wrapper for solving Binance captcha.
114114
yidun(self, sitekey, pageurl, **kwargs)
115115
Wrapper for solving Yidun captcha.
116+
hunt(self, pageurl, api_get_lib, **kwargs)
117+
Wrapper for solving Hunt captcha.
116118
solve(timeout=0, polling_interval=0, **kwargs)
117119
Sends CAPTCHA data and retrieves the result.
118120
balance()
@@ -1219,6 +1221,31 @@ def yidun(self, sitekey, pageurl, **kwargs):
12191221

12201222
return result
12211223

1224+
def hunt(self, pageurl, api_get_lib, **kwargs):
1225+
'''Wrapper for solving Hunt captcha.
1226+
1227+
Parameters
1228+
__________
1229+
pageurl : str
1230+
Full URL of the page with the captcha.
1231+
api_get_lib : str
1232+
Full link to the api.js file that loads the captcha on the page.
1233+
data : str, optional
1234+
Value of `meta.token` that the site returned after a request with X-HD.
1235+
Use only for the captcha solving mode (second step).
1236+
useragent : str, optional
1237+
Browser User-Agent used to open the page.
1238+
proxy : dict, optional
1239+
{'type': 'HTTPS', 'uri': 'login:password@IP_address:PORT'}.
1240+
'''
1241+
result = self.solve(
1242+
method="hunt",
1243+
pageurl=pageurl,
1244+
api_get_lib=api_get_lib,
1245+
**kwargs)
1246+
1247+
return result
1248+
12221249

12231250
def solve(self, timeout=0, polling_interval=0, **kwargs):
12241251
'''Sends captcha, receives result.

0 commit comments

Comments
 (0)