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.
@@ -1 +1 @@
1
- __version__ = "6.5.0"
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()
@@ -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()
@@ -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
- redirectUri: str,
11
- userAgent: str,
12
- proxyType: str,
13
- proxyAddress: str,
14
- proxyPort: str,
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: dict[str, Any],
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
- redirectUri: The URL that is returned on requests to the captcha API.
24
- userAgent: User-Agent of your browser will be used to load the captcha.
25
- Use only modern browser's User-Agents
26
- proxyType: Proxy type - `http`, `socks4`, `socks5`
27
- proxyAddress: Proxy IP address or hostname
28
- proxyPort: Proxy port
29
- method: Captcha type
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="445",
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="445",
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=VKCaptchaEnm.VKCaptchaTask, *args, **kwargs)
116
+ super().__init__(method=method, *args, **kwargs)
84
117
 
85
- self.create_task_payload["task"].update(
86
- {
87
- "websiteURL": redirectUri,
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(self, **kwargs: dict[str, Any]) -> dict[str, Any]:
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(self) -> dict[str, Any]:
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()