python-rucaptcha 6.5.0__py3-none-any.whl → 6.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_rucaptcha/__version__.py +1 -1
- python_rucaptcha/altcha_captcha.py +152 -0
- python_rucaptcha/binance_captcha.py +155 -0
- python_rucaptcha/core/enums.py +21 -0
- python_rucaptcha/core/result_handler.py +0 -1
- python_rucaptcha/vk_captcha.py +130 -25
- python_rucaptcha/yandex_smart_captcha.py +246 -0
- python_rucaptcha/yidun_captcha.py +171 -0
- python_rucaptcha-6.6.0.dist-info/METADATA +194 -0
- {python_rucaptcha-6.5.0.dist-info → python_rucaptcha-6.6.0.dist-info}/RECORD +13 -9
- {python_rucaptcha-6.5.0.dist-info → python_rucaptcha-6.6.0.dist-info}/WHEEL +1 -1
- python_rucaptcha-6.5.0.dist-info/METADATA +0 -108
- {python_rucaptcha-6.5.0.dist-info → python_rucaptcha-6.6.0.dist-info}/licenses/LICENSE +0 -0
- {python_rucaptcha-6.5.0.dist-info → python_rucaptcha-6.6.0.dist-info}/top_level.txt +0 -0
python_rucaptcha/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "6.
|
|
1
|
+
__version__ = "6.6.0"
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from typing import Union, Optional
|
|
2
|
+
|
|
3
|
+
from .core.base import BaseCaptcha
|
|
4
|
+
from .core.enums import AltchaEnm
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AltchaCaptcha(BaseCaptcha):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
websiteURL: str,
|
|
11
|
+
method: Union[str, AltchaEnm] = AltchaEnm.AltchaTaskProxyless,
|
|
12
|
+
challengeURL: Optional[str] = None,
|
|
13
|
+
challengeJSON: Optional[str] = None,
|
|
14
|
+
proxyType: Optional[str] = None,
|
|
15
|
+
proxyAddress: Optional[str] = None,
|
|
16
|
+
proxyPort: Optional[int] = None,
|
|
17
|
+
proxyLogin: Optional[str] = None,
|
|
18
|
+
proxyPassword: Optional[str] = None,
|
|
19
|
+
*args,
|
|
20
|
+
**kwargs,
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
The class is used to work with ALTCHA captcha.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
rucaptcha_key: User API key
|
|
27
|
+
websiteURL: Full URL of the captcha page
|
|
28
|
+
method: Captcha type
|
|
29
|
+
challengeURL: Full URL of the page that contains ALTCHA challenge
|
|
30
|
+
challengeJSON: JSON-encoded ALTCHA challenge data
|
|
31
|
+
proxyType: Proxy type (http, https, socks4, socks5)
|
|
32
|
+
proxyAddress: Proxy IP address or hostname
|
|
33
|
+
proxyPort: Proxy port
|
|
34
|
+
proxyLogin: Proxy login
|
|
35
|
+
proxyPassword: Proxy password
|
|
36
|
+
kwargs: Not required params for task creation request
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
>>> AltchaCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
40
|
+
... websiteURL="https://example.com",
|
|
41
|
+
... challengeURL="https://example.com/altcha/challenge.js",
|
|
42
|
+
... method=AltchaEnm.AltchaTaskProxyless.value,
|
|
43
|
+
... ).captcha_handler()
|
|
44
|
+
{
|
|
45
|
+
"errorId":0,
|
|
46
|
+
"status":"ready",
|
|
47
|
+
"solution":{
|
|
48
|
+
"token":"..."
|
|
49
|
+
},
|
|
50
|
+
"cost":"0.00145",
|
|
51
|
+
"ip":"1.2.3.4",
|
|
52
|
+
"createTime":1692863536,
|
|
53
|
+
"endTime":1692863556,
|
|
54
|
+
"solveCount":1,
|
|
55
|
+
"taskId": 73243152973,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
>>> await AltchaCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
59
|
+
... websiteURL="https://example.com",
|
|
60
|
+
... challengeJSON='{"挑战数据"}',
|
|
61
|
+
... method=AltchaEnm.AltchaTask.value,
|
|
62
|
+
... proxyType="http",
|
|
63
|
+
... proxyAddress="1.2.3.4",
|
|
64
|
+
... proxyPort=8080,
|
|
65
|
+
... ).aio_captcha_handler()
|
|
66
|
+
{
|
|
67
|
+
"errorId":0,
|
|
68
|
+
"status":"ready",
|
|
69
|
+
"solution":{
|
|
70
|
+
"token":"..."
|
|
71
|
+
},
|
|
72
|
+
"cost":"0.00145",
|
|
73
|
+
"ip":"1.2.3.4",
|
|
74
|
+
"createTime":1692863536,
|
|
75
|
+
"endTime":1692863556,
|
|
76
|
+
"solveCount":1,
|
|
77
|
+
"taskId": 73243152973,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Dict with full server response
|
|
82
|
+
|
|
83
|
+
Notes:
|
|
84
|
+
https://rucaptcha.com/api-docs/altcha
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
super().__init__(method=method, *args, **kwargs)
|
|
88
|
+
|
|
89
|
+
# XOR validation: exactly one of challengeURL or challengeJSON must be provided
|
|
90
|
+
if not (bool(challengeURL) ^ bool(challengeJSON)):
|
|
91
|
+
raise ValueError(
|
|
92
|
+
"Exactly one of 'challengeURL' or 'challengeJSON' must be provided, not both or neither"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# Validate method
|
|
96
|
+
if method not in AltchaEnm.list_values():
|
|
97
|
+
raise ValueError(f"Invalid method parameter set, available - {AltchaEnm.list_values()}")
|
|
98
|
+
|
|
99
|
+
# Build task payload
|
|
100
|
+
task_data = {"websiteURL": websiteURL}
|
|
101
|
+
|
|
102
|
+
if challengeURL:
|
|
103
|
+
task_data["challengeURL"] = challengeURL
|
|
104
|
+
|
|
105
|
+
if challengeJSON:
|
|
106
|
+
task_data["challengeJSON"] = challengeJSON
|
|
107
|
+
|
|
108
|
+
# Add proxy params only for non-proxyless methods
|
|
109
|
+
if method == AltchaEnm.AltchaTask.value:
|
|
110
|
+
if not all([proxyType, proxyAddress, proxyPort]):
|
|
111
|
+
raise ValueError(
|
|
112
|
+
"Proxy parameters (proxyType, proxyAddress, proxyPort) are required for AltchaTask"
|
|
113
|
+
)
|
|
114
|
+
task_data.update(
|
|
115
|
+
{
|
|
116
|
+
"proxyType": proxyType,
|
|
117
|
+
"proxyAddress": proxyAddress,
|
|
118
|
+
"proxyPort": proxyPort,
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
if proxyLogin and proxyPassword:
|
|
122
|
+
task_data["proxyLogin"] = proxyLogin
|
|
123
|
+
task_data["proxyPassword"] = proxyPassword
|
|
124
|
+
|
|
125
|
+
self.create_task_payload["task"].update(task_data)
|
|
126
|
+
|
|
127
|
+
def captcha_handler(self, **kwargs) -> dict:
|
|
128
|
+
"""
|
|
129
|
+
Sync solving method
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
kwargs: Parameters for the `requests` library
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Dict with full server response
|
|
136
|
+
|
|
137
|
+
Notes:
|
|
138
|
+
Check class docstirng for more info
|
|
139
|
+
"""
|
|
140
|
+
return self._processing_response(**kwargs)
|
|
141
|
+
|
|
142
|
+
async def aio_captcha_handler(self) -> dict:
|
|
143
|
+
"""
|
|
144
|
+
Async solving method
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Dict with full server response
|
|
148
|
+
|
|
149
|
+
Notes:
|
|
150
|
+
Check class docstirng for more info
|
|
151
|
+
"""
|
|
152
|
+
return await self._aio_processing_response()
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from typing import Union, Optional
|
|
2
|
+
|
|
3
|
+
from .core.base import BaseCaptcha
|
|
4
|
+
from .core.enums import BinanceCaptchaEnm
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BinanceCaptcha(BaseCaptcha):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
websiteURL: str,
|
|
11
|
+
websiteKey: str,
|
|
12
|
+
validateId: str,
|
|
13
|
+
method: Union[str, BinanceCaptchaEnm] = BinanceCaptchaEnm.BinanceTaskProxyless,
|
|
14
|
+
userAgent: Optional[str] = None,
|
|
15
|
+
proxyType: Optional[str] = None,
|
|
16
|
+
proxyAddress: Optional[str] = None,
|
|
17
|
+
proxyPort: Optional[int] = None,
|
|
18
|
+
proxyLogin: Optional[str] = None,
|
|
19
|
+
proxyPassword: Optional[str] = None,
|
|
20
|
+
*args,
|
|
21
|
+
**kwargs,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
The class is used to work with Binance CAPTCHA.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
rucaptcha_key: User API key
|
|
28
|
+
websiteURL: Full URL of the page where the captcha is loaded
|
|
29
|
+
websiteKey: Value of bizId, bizType, or bizCode from page requests
|
|
30
|
+
validateId: Dynamic value of validateId, securityId, or securityCheckResponseValidateId
|
|
31
|
+
method: Captcha type
|
|
32
|
+
userAgent: User-Agent string to be used when solving the captcha
|
|
33
|
+
proxyType: Proxy type (http, https, socks4, socks5)
|
|
34
|
+
proxyAddress: Proxy IP address or hostname
|
|
35
|
+
proxyPort: Proxy port
|
|
36
|
+
proxyLogin: Proxy login
|
|
37
|
+
proxyPassword: Proxy password
|
|
38
|
+
|
|
39
|
+
Examples:
|
|
40
|
+
>>> BinanceCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
41
|
+
... websiteURL="https://example.com/page-with-binance",
|
|
42
|
+
... websiteKey="login",
|
|
43
|
+
... validateId="cb0bfefa598...e54ecd57b",
|
|
44
|
+
... userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
|
45
|
+
... "(KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
|
|
46
|
+
... method=BinanceCaptchaEnm.BinanceTaskProxyless.value,
|
|
47
|
+
... ).captcha_handler()
|
|
48
|
+
{
|
|
49
|
+
"errorId":0,
|
|
50
|
+
"status":"ready",
|
|
51
|
+
"solution":{
|
|
52
|
+
"token":"captcha#09ba4905a79f44f...kc99maS943qIsquNP9D77",
|
|
53
|
+
"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
|
54
|
+
},
|
|
55
|
+
"cost":"0.00299",
|
|
56
|
+
"ip":"1.2.3.4",
|
|
57
|
+
"createTime":1692863536,
|
|
58
|
+
"endTime":1692863556,
|
|
59
|
+
"solveCount":1,
|
|
60
|
+
"taskId": 73243152973,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
>>> await BinanceCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
64
|
+
... websiteURL="https://example.com/page-with-binance",
|
|
65
|
+
... websiteKey="login",
|
|
66
|
+
... validateId="cb0bfefa598...e54ecd57b",
|
|
67
|
+
... method=BinanceCaptchaEnm.BinanceTask.value,
|
|
68
|
+
... proxyType="http",
|
|
69
|
+
... proxyAddress="1.2.3.4",
|
|
70
|
+
... proxyPort=8080,
|
|
71
|
+
... ).aio_captcha_handler()
|
|
72
|
+
{
|
|
73
|
+
"errorId":0,
|
|
74
|
+
"status":"ready",
|
|
75
|
+
"solution":{
|
|
76
|
+
"token":"captcha#09ba4905a79f44f...kc99maS943qIsquNP9D77",
|
|
77
|
+
"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
|
|
78
|
+
},
|
|
79
|
+
"cost":"0.00299",
|
|
80
|
+
"ip":"1.2.3.4",
|
|
81
|
+
"createTime":1692863536,
|
|
82
|
+
"endTime":1692863556,
|
|
83
|
+
"solveCount":1,
|
|
84
|
+
"taskId": 73243152973,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Dict with full server response
|
|
89
|
+
|
|
90
|
+
Notes:
|
|
91
|
+
https://2captcha.com/api-docs/binance-captcha
|
|
92
|
+
|
|
93
|
+
https://rucaptcha.com/api-docs/binance-captcha
|
|
94
|
+
"""
|
|
95
|
+
super().__init__(method=method, *args, **kwargs)
|
|
96
|
+
|
|
97
|
+
# Validate method
|
|
98
|
+
if method not in BinanceCaptchaEnm.list_values():
|
|
99
|
+
raise ValueError(f"Invalid method parameter set, available - {BinanceCaptchaEnm.list_values()}")
|
|
100
|
+
|
|
101
|
+
# Build task payload
|
|
102
|
+
task_data = {
|
|
103
|
+
"websiteURL": websiteURL,
|
|
104
|
+
"websiteKey": websiteKey,
|
|
105
|
+
"validateId": validateId,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if userAgent:
|
|
109
|
+
task_data["userAgent"] = userAgent
|
|
110
|
+
|
|
111
|
+
# Add proxy params only for non-proxyless methods
|
|
112
|
+
if method == BinanceCaptchaEnm.BinanceTask.value:
|
|
113
|
+
if not all([proxyType, proxyAddress, proxyPort]):
|
|
114
|
+
raise ValueError(
|
|
115
|
+
"Proxy parameters (proxyType, proxyAddress, proxyPort) are required for BinanceTask"
|
|
116
|
+
)
|
|
117
|
+
task_data.update(
|
|
118
|
+
{
|
|
119
|
+
"proxyType": proxyType,
|
|
120
|
+
"proxyAddress": proxyAddress,
|
|
121
|
+
"proxyPort": proxyPort,
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
if proxyLogin and proxyPassword:
|
|
125
|
+
task_data["proxyLogin"] = proxyLogin
|
|
126
|
+
task_data["proxyPassword"] = proxyPassword
|
|
127
|
+
|
|
128
|
+
self.create_task_payload["task"].update(task_data)
|
|
129
|
+
|
|
130
|
+
def captcha_handler(self, **kwargs) -> dict:
|
|
131
|
+
"""
|
|
132
|
+
Sync solving method
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
kwargs: Parameters for the `requests` library
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Dict with full server response
|
|
139
|
+
|
|
140
|
+
Notes:
|
|
141
|
+
Check class docstirng for more info
|
|
142
|
+
"""
|
|
143
|
+
return self._processing_response(**kwargs)
|
|
144
|
+
|
|
145
|
+
async def aio_captcha_handler(self) -> dict:
|
|
146
|
+
"""
|
|
147
|
+
Async solving method
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Dict with full server response
|
|
151
|
+
|
|
152
|
+
Notes:
|
|
153
|
+
Check class docstirng for more info
|
|
154
|
+
"""
|
|
155
|
+
return await self._aio_processing_response()
|
python_rucaptcha/core/enums.py
CHANGED
|
@@ -98,6 +98,11 @@ class TurnstileCaptchaEnm(str, MyEnum):
|
|
|
98
98
|
TurnstileTask = "TurnstileTask"
|
|
99
99
|
|
|
100
100
|
|
|
101
|
+
class AltchaEnm(str, MyEnum):
|
|
102
|
+
AltchaTaskProxyless = "AltchaTaskProxyless"
|
|
103
|
+
AltchaTask = "AltchaTask"
|
|
104
|
+
|
|
105
|
+
|
|
101
106
|
class AmazonWAFCaptchaEnm(str, MyEnum):
|
|
102
107
|
AmazonTask = "AmazonTask"
|
|
103
108
|
AmazonTaskProxyless = "AmazonTaskProxyless"
|
|
@@ -172,7 +177,23 @@ class CaptchaFoxEnm(str, MyEnum):
|
|
|
172
177
|
|
|
173
178
|
class VKCaptchaEnm(str, MyEnum):
|
|
174
179
|
VKCaptchaTask = "VKCaptchaTask"
|
|
180
|
+
VKCaptchaImageTask = "VKCaptchaImageTask"
|
|
175
181
|
|
|
176
182
|
|
|
177
183
|
class TemuCaptchaEnm(str, MyEnum):
|
|
178
184
|
TemuCaptchaTask = "TemuCaptchaTask"
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class BinanceCaptchaEnm(str, MyEnum):
|
|
188
|
+
BinanceTaskProxyless = "BinanceTaskProxyless"
|
|
189
|
+
BinanceTask = "BinanceTask"
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class YidunEnm(str, MyEnum):
|
|
193
|
+
YidunTaskProxyless = "YidunTaskProxyless"
|
|
194
|
+
YidunTask = "YidunTask"
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class YandexSmartCaptchaEnm(str, MyEnum):
|
|
198
|
+
YandexSmartCaptchaTaskProxyless = "YandexSmartCaptchaTaskProxyless"
|
|
199
|
+
YandexSmartCaptchaTask = "YandexSmartCaptchaTask"
|
|
@@ -35,7 +35,6 @@ def get_sync_result(
|
|
|
35
35
|
occurs, the dictionary includes error details such as status, errorId, errorCode,
|
|
36
36
|
and errorDescription.
|
|
37
37
|
"""
|
|
38
|
-
logging.warning(f"{url_response = }")
|
|
39
38
|
response_ser = GetTaskResultResponseSer(taskId=get_payload.taskId)
|
|
40
39
|
# generator for repeated attempts to connect to the server
|
|
41
40
|
attempts = attempts_generator()
|
python_rucaptcha/vk_captcha.py
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any, Union, Optional
|
|
2
2
|
|
|
3
3
|
from .core.base import BaseCaptcha
|
|
4
|
-
from .core.enums import VKCaptchaEnm
|
|
4
|
+
from .core.enums import VKCaptchaEnm, SaveFormatsEnm
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class VKCaptcha(BaseCaptcha):
|
|
8
8
|
def __init__(
|
|
9
9
|
self,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
method: Union[str, VKCaptchaEnm] = VKCaptchaEnm.VKCaptchaTask,
|
|
11
|
+
redirectUri: Optional[str] = None,
|
|
12
|
+
userAgent: Optional[str] = None,
|
|
13
|
+
proxyType: Optional[str] = None,
|
|
14
|
+
proxyAddress: Optional[str] = None,
|
|
15
|
+
proxyPort: Optional[int] = None,
|
|
16
|
+
proxyLogin: Optional[str] = None,
|
|
17
|
+
proxyPassword: Optional[str] = None,
|
|
18
|
+
save_format: Union[str, SaveFormatsEnm] = SaveFormatsEnm.TEMP,
|
|
19
|
+
img_path: str = "PythonRuCaptchaImages",
|
|
15
20
|
*args,
|
|
16
|
-
**kwargs
|
|
21
|
+
**kwargs,
|
|
17
22
|
):
|
|
18
23
|
"""
|
|
19
|
-
The class is used to work with VKCaptchaTask.
|
|
24
|
+
The class is used to work with VKCaptchaTask and VKCaptchaImageTask.
|
|
25
|
+
|
|
26
|
+
VKCaptchaTask requires proxy and returns a token.
|
|
27
|
+
VKCaptchaImageTask takes a captcha image and steps, returns image solution.
|
|
20
28
|
|
|
21
29
|
Args:
|
|
22
30
|
rucaptcha_key: User API key
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
proxyType: Proxy type -
|
|
27
|
-
proxyAddress: Proxy IP address or hostname
|
|
28
|
-
proxyPort: Proxy port
|
|
29
|
-
|
|
31
|
+
method: Captcha type - VKCaptchaTask or VKCaptchaImageTask
|
|
32
|
+
redirectUri: The URL that is returned on requests to the captcha API (VKCaptchaTask)
|
|
33
|
+
userAgent: User-Agent of your browser will be used to load the captcha (VKCaptchaTask)
|
|
34
|
+
proxyType: Proxy type - http, https, socks5 (VKCaptchaTask)
|
|
35
|
+
proxyAddress: Proxy IP address or hostname (VKCaptchaTask)
|
|
36
|
+
proxyPort: Proxy port (VKCaptchaTask)
|
|
37
|
+
proxyLogin: Proxy login (VKCaptchaTask)
|
|
38
|
+
proxyPassword: Proxy password (VKCaptchaTask)
|
|
39
|
+
save_format: Image save format for VKCaptchaImageTask - 'temp' or 'const'
|
|
40
|
+
img_path: Folder to save captcha images for VKCaptchaImageTask
|
|
30
41
|
kwargs: Not required params for task creation request
|
|
31
42
|
|
|
32
43
|
Examples:
|
|
@@ -35,7 +46,7 @@ class VKCaptcha(BaseCaptcha):
|
|
|
35
46
|
... userAgent="Mozilla/5.0 .....",
|
|
36
47
|
... proxyType="socks5",
|
|
37
48
|
... proxyAddress="1.2.3.4",
|
|
38
|
-
... proxyPort=
|
|
49
|
+
... proxyPort=445,
|
|
39
50
|
... ).captcha_handler()
|
|
40
51
|
{
|
|
41
52
|
"errorId":0,
|
|
@@ -56,7 +67,7 @@ class VKCaptcha(BaseCaptcha):
|
|
|
56
67
|
... userAgent="Mozilla/5.0 .....",
|
|
57
68
|
... proxyType="socks5",
|
|
58
69
|
... proxyAddress="1.2.3.4",
|
|
59
|
-
... proxyPort=
|
|
70
|
+
... proxyPort=445,
|
|
60
71
|
... ).aio_captcha_handler()
|
|
61
72
|
{
|
|
62
73
|
"errorId":0,
|
|
@@ -72,6 +83,28 @@ class VKCaptcha(BaseCaptcha):
|
|
|
72
83
|
"taskId": 73243152973,
|
|
73
84
|
}
|
|
74
85
|
|
|
86
|
+
>>> VKCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
87
|
+
... method=VKCaptchaEnm.VKCaptchaImageTask,
|
|
88
|
+
... ).captcha_handler(
|
|
89
|
+
... captcha_link="https://example.com/vk_captcha.png", steps=[3, 4, 5]
|
|
90
|
+
... )
|
|
91
|
+
{
|
|
92
|
+
"errorId":0,
|
|
93
|
+
"status":"ready",
|
|
94
|
+
"solution":{
|
|
95
|
+
"best_step": 1,
|
|
96
|
+
"preview": "...",
|
|
97
|
+
"solution": "...",
|
|
98
|
+
"answer": "..."
|
|
99
|
+
},
|
|
100
|
+
"cost":"0.002",
|
|
101
|
+
"ip":"1.2.3.4",
|
|
102
|
+
"createTime":1692863536,
|
|
103
|
+
"endTime":1692863556,
|
|
104
|
+
"solveCount":0,
|
|
105
|
+
"taskId": 73243152973,
|
|
106
|
+
}
|
|
107
|
+
|
|
75
108
|
Returns:
|
|
76
109
|
Dict with full server response
|
|
77
110
|
|
|
@@ -80,23 +113,51 @@ class VKCaptcha(BaseCaptcha):
|
|
|
80
113
|
|
|
81
114
|
https://rucaptcha.com/api-docs/vk-captcha
|
|
82
115
|
"""
|
|
83
|
-
super().__init__(method=
|
|
116
|
+
super().__init__(method=method, *args, **kwargs)
|
|
84
117
|
|
|
85
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
118
|
+
if method not in VKCaptchaEnm.list_values():
|
|
119
|
+
raise ValueError(f"Invalid method parameter set, available - {VKCaptchaEnm.list_values()}")
|
|
120
|
+
|
|
121
|
+
self.method = method
|
|
122
|
+
self.save_format = save_format
|
|
123
|
+
self.img_path = img_path
|
|
124
|
+
|
|
125
|
+
if method == VKCaptchaEnm.VKCaptchaTask:
|
|
126
|
+
if not all([redirectUri, userAgent, proxyType, proxyAddress, proxyPort]):
|
|
127
|
+
raise ValueError(
|
|
128
|
+
"redirectUri, userAgent, proxyType, proxyAddress, "
|
|
129
|
+
"and proxyPort are required for VKCaptchaTask"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
task_data = {
|
|
133
|
+
"redirectUri": redirectUri,
|
|
88
134
|
"userAgent": userAgent,
|
|
89
135
|
"proxyType": proxyType,
|
|
90
136
|
"proxyAddress": proxyAddress,
|
|
91
137
|
"proxyPort": proxyPort,
|
|
92
138
|
}
|
|
93
|
-
|
|
139
|
+
if proxyLogin and proxyPassword:
|
|
140
|
+
task_data["proxyLogin"] = proxyLogin
|
|
141
|
+
task_data["proxyPassword"] = proxyPassword
|
|
142
|
+
|
|
143
|
+
self.create_task_payload["task"].update(task_data)
|
|
94
144
|
|
|
95
|
-
def captcha_handler(
|
|
145
|
+
def captcha_handler(
|
|
146
|
+
self,
|
|
147
|
+
captcha_link: Optional[str] = None,
|
|
148
|
+
captcha_file: Optional[str] = None,
|
|
149
|
+
captcha_base64: Optional[bytes] = None,
|
|
150
|
+
steps: Optional[list[int]] = None,
|
|
151
|
+
**kwargs: dict[str, Any],
|
|
152
|
+
) -> dict[str, Any]:
|
|
96
153
|
"""
|
|
97
154
|
Sync solving method
|
|
98
155
|
|
|
99
156
|
Args:
|
|
157
|
+
captcha_link: Captcha image URL (VKCaptchaImageTask)
|
|
158
|
+
captcha_file: Captcha image file path (VKCaptchaImageTask)
|
|
159
|
+
captcha_base64: Captcha image BASE64 info (VKCaptchaImageTask)
|
|
160
|
+
steps: List of step values for VKCaptchaImageTask
|
|
100
161
|
kwargs: additional params for `requests` library
|
|
101
162
|
|
|
102
163
|
Returns:
|
|
@@ -105,16 +166,60 @@ class VKCaptcha(BaseCaptcha):
|
|
|
105
166
|
Notes:
|
|
106
167
|
Check class docstirng for more info
|
|
107
168
|
"""
|
|
169
|
+
if self.method == VKCaptchaEnm.VKCaptchaImageTask:
|
|
170
|
+
self._body_file_processing(
|
|
171
|
+
save_format=self.save_format,
|
|
172
|
+
file_path=self.img_path,
|
|
173
|
+
image_key="image",
|
|
174
|
+
captcha_link=captcha_link,
|
|
175
|
+
captcha_file=captcha_file,
|
|
176
|
+
captcha_base64=captcha_base64,
|
|
177
|
+
)
|
|
178
|
+
if steps:
|
|
179
|
+
self.create_task_payload["task"]["steps"] = steps
|
|
180
|
+
if not self.result.errorId:
|
|
181
|
+
return self._processing_response(**kwargs)
|
|
182
|
+
return self.result.to_dict()
|
|
183
|
+
|
|
108
184
|
return self._processing_response(**kwargs)
|
|
109
185
|
|
|
110
|
-
async def aio_captcha_handler(
|
|
186
|
+
async def aio_captcha_handler(
|
|
187
|
+
self,
|
|
188
|
+
captcha_link: Optional[str] = None,
|
|
189
|
+
captcha_file: Optional[str] = None,
|
|
190
|
+
captcha_base64: Optional[bytes] = None,
|
|
191
|
+
steps: Optional[list[int]] = None,
|
|
192
|
+
**kwargs: dict[str, Any],
|
|
193
|
+
) -> dict[str, Any]:
|
|
111
194
|
"""
|
|
112
195
|
Async solving method
|
|
113
196
|
|
|
197
|
+
Args:
|
|
198
|
+
captcha_link: Captcha image URL (VKCaptchaImageTask)
|
|
199
|
+
captcha_file: Captcha image file path (VKCaptchaImageTask)
|
|
200
|
+
captcha_base64: Captcha image BASE64 info (VKCaptchaImageTask)
|
|
201
|
+
steps: List of step values for VKCaptchaImageTask
|
|
202
|
+
kwargs: additional params for `aiohttp` library
|
|
203
|
+
|
|
114
204
|
Returns:
|
|
115
205
|
Dict with full server response
|
|
116
206
|
|
|
117
207
|
Notes:
|
|
118
208
|
Check class docstirng for more info
|
|
119
209
|
"""
|
|
210
|
+
if self.method == VKCaptchaEnm.VKCaptchaImageTask:
|
|
211
|
+
await self._aio_body_file_processing(
|
|
212
|
+
save_format=self.save_format,
|
|
213
|
+
file_path=self.img_path,
|
|
214
|
+
image_key="image",
|
|
215
|
+
captcha_link=captcha_link,
|
|
216
|
+
captcha_file=captcha_file,
|
|
217
|
+
captcha_base64=captcha_base64,
|
|
218
|
+
)
|
|
219
|
+
if steps:
|
|
220
|
+
self.create_task_payload["task"]["steps"] = steps
|
|
221
|
+
if not self.result.errorId:
|
|
222
|
+
return await self._aio_processing_response()
|
|
223
|
+
return self.result.to_dict()
|
|
224
|
+
|
|
120
225
|
return await self._aio_processing_response()
|