python3-capsolver 0.9.2__py3-none-any.whl → 1.0.0a0__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.
- python3_capsolver/__init__.py +1 -0
- python3_capsolver/__version__.py +1 -1
- python3_capsolver/aws_waf.py +122 -95
- python3_capsolver/cloudflare.py +77 -96
- python3_capsolver/control.py +31 -29
- python3_capsolver/core/aio_captcha_instrument.py +109 -0
- python3_capsolver/core/base.py +52 -198
- python3_capsolver/core/captcha_instrument.py +145 -0
- python3_capsolver/core/const.py +27 -0
- python3_capsolver/core/context_instr.py +25 -0
- python3_capsolver/core/enum.py +21 -76
- python3_capsolver/core/serializer.py +35 -129
- python3_capsolver/core/sio_captcha_instrument.py +116 -0
- python3_capsolver/core/{config.py → utils.py} +1 -10
- python3_capsolver/datadome_slider.py +34 -84
- python3_capsolver/friendly_captcha.py +69 -0
- python3_capsolver/gee_test.py +58 -90
- python3_capsolver/image_to_text.py +86 -116
- python3_capsolver/mt_captcha.py +32 -108
- python3_capsolver/recaptcha.py +65 -129
- python3_capsolver/vision_engine.py +102 -0
- python3_capsolver/yandex.py +53 -0
- python3_capsolver-1.0.0a0.dist-info/LICENSE +21 -0
- {python3_capsolver-0.9.2.dist-info → python3_capsolver-1.0.0a0.dist-info}/METADATA +25 -55
- python3_capsolver-1.0.0a0.dist-info/RECORD +28 -0
- {python3_capsolver-0.9.2.dist-info → python3_capsolver-1.0.0a0.dist-info}/WHEEL +1 -1
- python3_capsolver/akamai.py +0 -192
- python3_capsolver/binance.py +0 -112
- python3_capsolver/cyber_si_ara.py +0 -128
- python3_capsolver/fun_captcha.py +0 -251
- python3_capsolver/hcaptcha.py +0 -197
- python3_capsolver/imperva.py +0 -120
- python3_capsolver-0.9.2.dist-info/RECORD +0 -25
- {python3_capsolver-0.9.2.dist-info → python3_capsolver-1.0.0a0.dist-info}/top_level.txt +0 -0
python3_capsolver/core/base.py
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
RequestCreateTaskSer,
|
|
18
|
-
RequestGetTaskResultSer,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class BaseCaptcha:
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
from python3_capsolver.core.enum import CaptchaTypeEnm
|
|
4
|
+
from python3_capsolver.core.serializer import TaskSer
|
|
5
|
+
|
|
6
|
+
from .const import REQUEST_URL
|
|
7
|
+
from .serializer import RequestCreateTaskSer, RequestGetTaskResultSer
|
|
8
|
+
from .context_instr import AIOContextManager, SIOContextManager
|
|
9
|
+
from .captcha_instrument import CaptchaInstrument
|
|
10
|
+
from .aio_captcha_instrument import AIOCaptchaInstrument
|
|
11
|
+
from .sio_captcha_instrument import SIOCaptchaInstrument
|
|
12
|
+
|
|
13
|
+
__all__ = ("CaptchaParams",)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CaptchaParams(SIOContextManager, AIOContextManager):
|
|
23
17
|
"""
|
|
24
18
|
Basic Captcha solving class
|
|
25
19
|
|
|
@@ -33,195 +27,55 @@ class BaseCaptcha:
|
|
|
33
27
|
def __init__(
|
|
34
28
|
self,
|
|
35
29
|
api_key: str,
|
|
30
|
+
captcha_type: CaptchaTypeEnm,
|
|
36
31
|
sleep_time: int = 5,
|
|
37
32
|
request_url: str = REQUEST_URL,
|
|
38
|
-
**kwargs,
|
|
39
33
|
):
|
|
40
34
|
# assign args to validator
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# prepare
|
|
45
|
-
self.
|
|
46
|
-
self.
|
|
47
|
-
self.
|
|
48
|
-
|
|
49
|
-
|
|
35
|
+
self.create_task_payload = RequestCreateTaskSer(clientKey=api_key)
|
|
36
|
+
# `task` body for task creation payload
|
|
37
|
+
self.task_params = TaskSer(type=captcha_type.value).to_dict()
|
|
38
|
+
# prepare `get task result` payload
|
|
39
|
+
self.get_result_params = RequestGetTaskResultSer(clientKey=api_key)
|
|
40
|
+
self.request_url = request_url
|
|
41
|
+
self._captcha_handling_instrument = CaptchaInstrument()
|
|
42
|
+
self.sleep_time = sleep_time
|
|
43
|
+
|
|
44
|
+
def captcha_handler(self, task_payload: Dict) -> Dict[str, str]:
|
|
50
45
|
"""
|
|
51
|
-
|
|
46
|
+
Synchronous method for captcha solving
|
|
52
47
|
|
|
53
48
|
Args:
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
task_payload: Some additional parameters that will be used in creating the task
|
|
50
|
+
and will be passed to the payload under ``task`` key.
|
|
51
|
+
Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs
|
|
56
52
|
|
|
57
|
-
Examples:
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
Returns:
|
|
55
|
+
Dict with full server response
|
|
60
56
|
|
|
57
|
+
Notes:
|
|
58
|
+
Check class docstirng for more info
|
|
61
59
|
"""
|
|
62
|
-
self.task_payload
|
|
63
|
-
|
|
64
|
-
self.
|
|
65
|
-
|
|
66
|
-
def __enter__(self):
|
|
67
|
-
return self
|
|
68
|
-
|
|
69
|
-
def __exit__(self, exc_type, exc_value, traceback):
|
|
70
|
-
if exc_type:
|
|
71
|
-
return False
|
|
72
|
-
return True
|
|
73
|
-
|
|
74
|
-
async def __aenter__(self):
|
|
75
|
-
return self
|
|
76
|
-
|
|
77
|
-
async def __aexit__(self, exc_type, exc_value, traceback):
|
|
78
|
-
if exc_type:
|
|
79
|
-
return False
|
|
80
|
-
return True
|
|
81
|
-
|
|
82
|
-
"""
|
|
83
|
-
Sync part
|
|
84
|
-
"""
|
|
60
|
+
self.task_params.update(task_payload)
|
|
61
|
+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
|
|
62
|
+
return self._captcha_handling_instrument.processing_captcha()
|
|
85
63
|
|
|
86
|
-
def
|
|
87
|
-
self, create_params: dict, serializer: Type[BaseModel] = RequestCreateTaskSer
|
|
88
|
-
) -> CaptchaResponseSer:
|
|
89
|
-
self._prepare_create_task_payload(serializer=serializer, create_params=create_params)
|
|
90
|
-
self.created_task_data = CaptchaResponseSer(**self._create_task())
|
|
91
|
-
|
|
92
|
-
# if task created and ready - return result
|
|
93
|
-
if self.created_task_data.status == ResponseStatusEnm.Ready.value:
|
|
94
|
-
return self.created_task_data
|
|
95
|
-
# if captcha is not ready but task success created - waiting captcha result
|
|
96
|
-
elif self.created_task_data.errorId == 0:
|
|
97
|
-
return self._get_result()
|
|
98
|
-
return self.created_task_data
|
|
99
|
-
|
|
100
|
-
def _create_task(self, url_postfix: str = EndpointPostfixEnm.CREATE_TASK.value) -> dict:
|
|
101
|
-
"""
|
|
102
|
-
Function send SYNC request to service and wait for result
|
|
64
|
+
async def aio_captcha_handler(self, task_payload: Dict) -> Dict[str, str]:
|
|
103
65
|
"""
|
|
104
|
-
|
|
105
|
-
resp = self.__session.post(
|
|
106
|
-
parse.urljoin(self.__request_url, url_postfix), json=self.task_payload.dict(exclude_none=True)
|
|
107
|
-
)
|
|
108
|
-
if resp.status_code in VALID_STATUS_CODES:
|
|
109
|
-
return resp.json()
|
|
110
|
-
else:
|
|
111
|
-
raise ValueError(resp.raise_for_status())
|
|
112
|
-
except Exception as error:
|
|
113
|
-
logging.exception(error)
|
|
114
|
-
raise
|
|
115
|
-
|
|
116
|
-
def _get_result(self, url_postfix: str = EndpointPostfixEnm.GET_TASK_RESULT.value) -> CaptchaResponseSer:
|
|
117
|
-
"""
|
|
118
|
-
Method send SYNC request to service and wait for result
|
|
119
|
-
"""
|
|
120
|
-
# initial waiting
|
|
121
|
-
time.sleep(self.__params.sleep_time)
|
|
122
|
-
|
|
123
|
-
get_result_payload = RequestGetTaskResultSer(
|
|
124
|
-
clientKey=self.__params.api_key, taskId=self.created_task_data.taskId
|
|
125
|
-
)
|
|
126
|
-
attempts = attempts_generator()
|
|
127
|
-
for _ in attempts:
|
|
128
|
-
try:
|
|
129
|
-
resp = self.__session.post(
|
|
130
|
-
parse.urljoin(self.__request_url, url_postfix), json=get_result_payload.dict(exclude_none=True)
|
|
131
|
-
)
|
|
132
|
-
if resp.status_code in VALID_STATUS_CODES:
|
|
133
|
-
result_data = CaptchaResponseSer(**resp.json())
|
|
134
|
-
if result_data.status in (ResponseStatusEnm.Ready, ResponseStatusEnm.Failed):
|
|
135
|
-
# if captcha ready\failed or have unknown status - return exist data
|
|
136
|
-
return result_data
|
|
137
|
-
else:
|
|
138
|
-
raise ValueError(resp.raise_for_status())
|
|
139
|
-
except Exception as error:
|
|
140
|
-
logging.exception(error)
|
|
141
|
-
raise
|
|
142
|
-
|
|
143
|
-
# if captcha just created or in processing now - wait
|
|
144
|
-
time.sleep(self.__params.sleep_time)
|
|
145
|
-
# default response if server is silent
|
|
146
|
-
return CaptchaResponseSer(
|
|
147
|
-
errorId=1,
|
|
148
|
-
errorCode="ERROR_CAPTCHA_UNSOLVABLE",
|
|
149
|
-
errorDescription="Captcha not recognized",
|
|
150
|
-
taskId=self.created_task_data.taskId,
|
|
151
|
-
status=ResponseStatusEnm.Failed,
|
|
152
|
-
)
|
|
66
|
+
Asynchronous method for captcha solving
|
|
153
67
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
68
|
+
Args:
|
|
69
|
+
task_payload: Some additional parameters that will be used in creating the task
|
|
70
|
+
and will be passed to the payload under ``task`` key.
|
|
71
|
+
Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs
|
|
157
72
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# if task created and already ready - return result
|
|
165
|
-
if self.created_task_data.status == ResponseStatusEnm.Ready.value:
|
|
166
|
-
return self.created_task_data
|
|
167
|
-
# if captcha is not ready but task success created - waiting captcha result
|
|
168
|
-
elif self.created_task_data.errorId == 0:
|
|
169
|
-
return await self._aio_get_result()
|
|
170
|
-
return self.created_task_data
|
|
171
|
-
|
|
172
|
-
async def _aio_create_task(self, url_postfix: str = EndpointPostfixEnm.CREATE_TASK.value) -> dict:
|
|
173
|
-
"""
|
|
174
|
-
Function send the ASYNC request to service and wait for result
|
|
175
|
-
"""
|
|
176
|
-
async with aiohttp.ClientSession() as session:
|
|
177
|
-
try:
|
|
178
|
-
async with session.post(
|
|
179
|
-
parse.urljoin(self.__request_url, url_postfix), json=self.task_payload.dict(exclude_none=True)
|
|
180
|
-
) as resp:
|
|
181
|
-
if resp.status in VALID_STATUS_CODES:
|
|
182
|
-
return await resp.json()
|
|
183
|
-
else:
|
|
184
|
-
raise ValueError(resp.reason)
|
|
185
|
-
except Exception as error:
|
|
186
|
-
logging.exception(error)
|
|
187
|
-
raise
|
|
188
|
-
|
|
189
|
-
async def _aio_get_result(self, url_postfix: str = EndpointPostfixEnm.GET_TASK_RESULT.value) -> CaptchaResponseSer:
|
|
190
|
-
"""
|
|
191
|
-
Function send the ASYNC request to service and wait for result
|
|
73
|
+
Returns:
|
|
74
|
+
Dict with full server response
|
|
75
|
+
|
|
76
|
+
Notes:
|
|
77
|
+
Check class docstirng for more info
|
|
192
78
|
"""
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
get_result_payload = RequestGetTaskResultSer(
|
|
197
|
-
clientKey=self.__params.api_key, taskId=self.created_task_data.taskId
|
|
198
|
-
)
|
|
199
|
-
attempts = attempts_generator()
|
|
200
|
-
async with aiohttp.ClientSession() as session:
|
|
201
|
-
for _ in attempts:
|
|
202
|
-
try:
|
|
203
|
-
async with session.post(
|
|
204
|
-
parse.urljoin(self.__request_url, url_postfix), json=get_result_payload.dict(exclude_none=True)
|
|
205
|
-
) as resp:
|
|
206
|
-
if resp.status in VALID_STATUS_CODES:
|
|
207
|
-
result_data = CaptchaResponseSer(**await resp.json())
|
|
208
|
-
if result_data.status in (ResponseStatusEnm.Ready, ResponseStatusEnm.Failed):
|
|
209
|
-
# if captcha ready\failed or have unknown status - return exist data
|
|
210
|
-
return result_data
|
|
211
|
-
else:
|
|
212
|
-
raise ValueError(resp.reason)
|
|
213
|
-
except Exception as error:
|
|
214
|
-
logging.exception(error)
|
|
215
|
-
raise
|
|
216
|
-
|
|
217
|
-
# if captcha just created or in processing now - wait
|
|
218
|
-
await asyncio.sleep(self.__params.sleep_time)
|
|
219
|
-
|
|
220
|
-
# default response if server is silent
|
|
221
|
-
return CaptchaResponseSer(
|
|
222
|
-
errorId=1,
|
|
223
|
-
errorCode="ERROR_CAPTCHA_UNSOLVABLE",
|
|
224
|
-
errorDescription="Captcha not recognized",
|
|
225
|
-
taskId=self.created_task_data.taskId,
|
|
226
|
-
status=ResponseStatusEnm.Failed,
|
|
227
|
-
)
|
|
79
|
+
self.task_params.update(task_payload)
|
|
80
|
+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
|
|
81
|
+
return await self._captcha_handling_instrument.processing_captcha()
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
import base64
|
|
4
|
+
import shutil
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import aiohttp
|
|
9
|
+
import requests
|
|
10
|
+
from requests.adapters import HTTPAdapter
|
|
11
|
+
|
|
12
|
+
from .enum import SaveFormatsEnm
|
|
13
|
+
from .const import RETRIES, ASYNC_RETRIES
|
|
14
|
+
from .serializer import CaptchaResponseSer
|
|
15
|
+
|
|
16
|
+
__all__ = ("CaptchaInstrument", "FileInstrument")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FileInstrument:
|
|
20
|
+
@staticmethod
|
|
21
|
+
def _local_file_captcha(captcha_file: str):
|
|
22
|
+
"""
|
|
23
|
+
Method get local file, read it and prepare for sending to Captcha solving service
|
|
24
|
+
"""
|
|
25
|
+
with open(captcha_file, "rb") as file:
|
|
26
|
+
return file.read()
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def _file_const_saver(content: bytes, file_path: str, file_extension: str = "png") -> str:
|
|
30
|
+
"""
|
|
31
|
+
Method create and save file in folder
|
|
32
|
+
"""
|
|
33
|
+
Path(file_path).mkdir(parents=True, exist_ok=True)
|
|
34
|
+
|
|
35
|
+
# generate image name
|
|
36
|
+
file_name = f"file-{uuid.uuid4()}.{file_extension}"
|
|
37
|
+
|
|
38
|
+
full_file_path = os.path.join(file_path, file_name)
|
|
39
|
+
|
|
40
|
+
# save image to folder
|
|
41
|
+
with open(full_file_path, "wb") as out_image:
|
|
42
|
+
out_image.write(content)
|
|
43
|
+
return full_file_path
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _file_clean(full_file_path: str):
|
|
47
|
+
shutil.rmtree(full_file_path, ignore_errors=True)
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def _url_read(url: str, **kwargs):
|
|
51
|
+
"""
|
|
52
|
+
Method open links
|
|
53
|
+
"""
|
|
54
|
+
# prepare session
|
|
55
|
+
session = requests.Session()
|
|
56
|
+
session.mount("http://", HTTPAdapter(max_retries=RETRIES))
|
|
57
|
+
session.mount("https://", HTTPAdapter(max_retries=RETRIES))
|
|
58
|
+
session.verify = False
|
|
59
|
+
return session.get(url=url, **kwargs)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
async def _aio_url_read(url: str, **kwargs) -> bytes:
|
|
63
|
+
"""
|
|
64
|
+
Async method read bytes from link
|
|
65
|
+
"""
|
|
66
|
+
async with aiohttp.ClientSession() as session:
|
|
67
|
+
async for attempt in ASYNC_RETRIES:
|
|
68
|
+
with attempt:
|
|
69
|
+
async with session.get(url=url, **kwargs) as resp:
|
|
70
|
+
return await resp.content.read()
|
|
71
|
+
|
|
72
|
+
def file_processing(
|
|
73
|
+
self,
|
|
74
|
+
captcha_link: Optional[str] = None,
|
|
75
|
+
captcha_file: Optional[str] = None,
|
|
76
|
+
captcha_base64: Optional[bytes] = None,
|
|
77
|
+
save_format: SaveFormatsEnm = SaveFormatsEnm.TEMP,
|
|
78
|
+
img_clearing: bool = True,
|
|
79
|
+
file_path: str = "/tmp/",
|
|
80
|
+
file_extension: str = "png",
|
|
81
|
+
**kwargs,
|
|
82
|
+
) -> str:
|
|
83
|
+
# if a local file link is passed
|
|
84
|
+
if captcha_file:
|
|
85
|
+
return base64.b64encode(self._local_file_captcha(captcha_file=captcha_file)).decode("utf-8")
|
|
86
|
+
# if the file is transferred in base64 encoding
|
|
87
|
+
elif captcha_base64:
|
|
88
|
+
return base64.b64encode(captcha_base64).decode("utf-8")
|
|
89
|
+
# if a URL is passed
|
|
90
|
+
elif captcha_link:
|
|
91
|
+
content = self._url_read(url=captcha_link, **kwargs).content
|
|
92
|
+
# according to the value of the passed parameter, select the function to save the image
|
|
93
|
+
if save_format == SaveFormatsEnm.CONST.value:
|
|
94
|
+
full_file_path = self._file_const_saver(content, file_path, file_extension=file_extension)
|
|
95
|
+
if img_clearing:
|
|
96
|
+
self._file_clean(full_file_path=full_file_path)
|
|
97
|
+
return base64.b64encode(content).decode("utf-8")
|
|
98
|
+
else:
|
|
99
|
+
raise ValueError("No valid captcha variant is set.")
|
|
100
|
+
|
|
101
|
+
async def aio_file_processing(
|
|
102
|
+
self,
|
|
103
|
+
captcha_link: Optional[str] = None,
|
|
104
|
+
captcha_file: Optional[str] = None,
|
|
105
|
+
captcha_base64: Optional[bytes] = None,
|
|
106
|
+
save_format: SaveFormatsEnm = SaveFormatsEnm.TEMP,
|
|
107
|
+
img_clearing: bool = True,
|
|
108
|
+
file_path: str = "/tmp/",
|
|
109
|
+
file_extension: str = "png",
|
|
110
|
+
**kwargs,
|
|
111
|
+
) -> str:
|
|
112
|
+
# if a local file link is passed
|
|
113
|
+
if captcha_file:
|
|
114
|
+
return base64.b64encode(self._local_file_captcha(captcha_file=captcha_file)).decode("utf-8")
|
|
115
|
+
# if the file is transferred in base64 encoding
|
|
116
|
+
elif captcha_base64:
|
|
117
|
+
return base64.b64encode(captcha_base64).decode("utf-8")
|
|
118
|
+
# if a URL is passed
|
|
119
|
+
elif captcha_link:
|
|
120
|
+
content = await self._aio_url_read(url=captcha_link, **kwargs)
|
|
121
|
+
# according to the value of the passed parameter, select the function to save the image
|
|
122
|
+
if save_format == SaveFormatsEnm.CONST.value:
|
|
123
|
+
full_file_path = self._file_const_saver(content, file_path, file_extension=file_extension)
|
|
124
|
+
if img_clearing:
|
|
125
|
+
self._file_clean(full_file_path=full_file_path)
|
|
126
|
+
return base64.b64encode(content).decode("utf-8")
|
|
127
|
+
|
|
128
|
+
else:
|
|
129
|
+
raise ValueError("No valid captcha variant is set.")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class CaptchaInstrument(FileInstrument):
|
|
133
|
+
CAPTCHA_UNSOLVABLE = "ERROR_CAPTCHA_UNSOLVABLE"
|
|
134
|
+
"""
|
|
135
|
+
Basic Captcha solving class
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
api_key: Capsolver API key
|
|
139
|
+
captcha_type: Captcha type name, like `ReCaptchaV2Task` and etc.
|
|
140
|
+
sleep_time: The waiting time between requests to get the result of the Captcha
|
|
141
|
+
request_url: API address for sending requests
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
def __init__(self):
|
|
145
|
+
self.result = CaptchaResponseSer()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import urllib3
|
|
2
|
+
from tenacity import AsyncRetrying, wait_fixed, stop_after_attempt
|
|
3
|
+
from requests.adapters import Retry
|
|
4
|
+
|
|
5
|
+
__all__ = (
|
|
6
|
+
"APP_ID",
|
|
7
|
+
"RETRIES",
|
|
8
|
+
"REQUEST_URL",
|
|
9
|
+
"ASYNC_RETRIES",
|
|
10
|
+
"GET_RESULT_POSTFIX",
|
|
11
|
+
"VALID_STATUS_CODES",
|
|
12
|
+
"GET_BALANCE_POSTFIX",
|
|
13
|
+
"CREATE_TASK_POSTFIX",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
17
|
+
|
|
18
|
+
RETRIES = Retry(total=5, backoff_factor=0.9, status_forcelist=[500, 502, 503, 504])
|
|
19
|
+
ASYNC_RETRIES = AsyncRetrying(wait=wait_fixed(5), stop=stop_after_attempt(5), reraise=True)
|
|
20
|
+
|
|
21
|
+
REQUEST_URL = "https://api.capsolver.com"
|
|
22
|
+
CREATE_TASK_POSTFIX = "/createTask"
|
|
23
|
+
GET_RESULT_POSTFIX = "/getTaskResult"
|
|
24
|
+
GET_BALANCE_POSTFIX = "/getBalance"
|
|
25
|
+
VALID_STATUS_CODES = (200, 202, 400, 401, 405)
|
|
26
|
+
|
|
27
|
+
APP_ID = "3E36E3CD-7EB5-4CAF-AA15-91011E652321"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
__all__ = ("SIOContextManager", "AIOContextManager")
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SIOContextManager:
|
|
5
|
+
|
|
6
|
+
# Context methods
|
|
7
|
+
def __enter__(self):
|
|
8
|
+
return self
|
|
9
|
+
|
|
10
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
|
11
|
+
if exc_type:
|
|
12
|
+
return False
|
|
13
|
+
return True
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AIOContextManager:
|
|
17
|
+
|
|
18
|
+
# Context methods
|
|
19
|
+
async def __aenter__(self):
|
|
20
|
+
return self
|
|
21
|
+
|
|
22
|
+
async def __aexit__(self, exc_type, exc_value, traceback):
|
|
23
|
+
if exc_type:
|
|
24
|
+
return False
|
|
25
|
+
return True
|
python3_capsolver/core/enum.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from types import DynamicClassAttribute
|
|
3
2
|
from typing import List
|
|
4
3
|
|
|
4
|
+
__all__ = ("EndpointPostfixEnm", "CaptchaTypeEnm", "ResponseStatusEnm", "SaveFormatsEnm")
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
class MyEnum(str, Enum):
|
|
7
8
|
@classmethod
|
|
8
9
|
def list(cls) -> List[Enum]:
|
|
9
10
|
return list(map(lambda c: c, cls))
|
|
@@ -16,22 +17,8 @@ class MyEnum(Enum):
|
|
|
16
17
|
def list_names(cls) -> List[str]:
|
|
17
18
|
return list(map(lambda c: c.name, cls))
|
|
18
19
|
|
|
19
|
-
@DynamicClassAttribute
|
|
20
|
-
def name(self) -> str:
|
|
21
|
-
"""
|
|
22
|
-
The name of the Enum member
|
|
23
|
-
"""
|
|
24
|
-
return self._name_
|
|
25
|
-
|
|
26
|
-
@DynamicClassAttribute
|
|
27
|
-
def value(self) -> str:
|
|
28
|
-
"""
|
|
29
|
-
The name of the Enum member
|
|
30
|
-
"""
|
|
31
|
-
return self._value_
|
|
32
20
|
|
|
33
|
-
|
|
34
|
-
class EndpointPostfixEnm(str, MyEnum):
|
|
21
|
+
class EndpointPostfixEnm(MyEnum):
|
|
35
22
|
"""
|
|
36
23
|
Enum stored URL postfixes for API endpoints
|
|
37
24
|
"""
|
|
@@ -39,93 +26,46 @@ class EndpointPostfixEnm(str, MyEnum):
|
|
|
39
26
|
GET_BALANCE = "getBalance"
|
|
40
27
|
CREATE_TASK = "createTask"
|
|
41
28
|
GET_TASK_RESULT = "getTaskResult"
|
|
42
|
-
AKAMAI_BMP_INVOKE = "akamaibmp/invoke"
|
|
43
|
-
AKAMAI_WEB_INVOKE = "akamaiweb/invoke"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class ImageToTextTaskTypeEnm(str, MyEnum):
|
|
47
|
-
ImageToTextTask = "ImageToTextTask"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class HCaptchaTypeEnm(str, MyEnum):
|
|
51
|
-
HCaptchaTask = "HCaptchaTask"
|
|
52
|
-
HCaptchaTaskProxyless = "HCaptchaTaskProxyless"
|
|
53
|
-
HCaptchaEnterpriseTask = "HCaptchaEnterpriseTask"
|
|
54
|
-
HCaptchaEnterpriseTaskProxyLess = "HCaptchaEnterpriseTaskProxyLess"
|
|
55
|
-
HCaptchaTurboTask = "HCaptchaTurboTask"
|
|
56
|
-
HCaptchaClassification = "HCaptchaClassification"
|
|
57
29
|
|
|
58
30
|
|
|
59
|
-
class
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class FunCaptchaTypeEnm(str, MyEnum):
|
|
64
|
-
FunCaptchaTask = "FunCaptchaTask"
|
|
65
|
-
FunCaptchaTaskProxyLess = "FunCaptchaTaskProxyLess"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class FunCaptchaClassificationTypeEnm(str, MyEnum):
|
|
69
|
-
FunCaptchaClassification = "FunCaptchaClassification"
|
|
31
|
+
class CaptchaTypeEnm(MyEnum):
|
|
32
|
+
Control = "Control"
|
|
70
33
|
|
|
34
|
+
ImageToTextTask = "ImageToTextTask"
|
|
35
|
+
VisionEngine = "VisionEngine"
|
|
71
36
|
|
|
72
|
-
class GeeTestCaptchaTypeEnm(str, MyEnum):
|
|
73
|
-
GeeTestTask = "GeeTestTask"
|
|
74
37
|
GeeTestTaskProxyLess = "GeeTestTaskProxyLess"
|
|
75
38
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# V2
|
|
39
|
+
# re-captcha
|
|
40
|
+
ReCaptchaV2Classification = "ReCaptchaV2Classification"
|
|
79
41
|
ReCaptchaV2Task = "ReCaptchaV2Task"
|
|
80
42
|
ReCaptchaV2EnterpriseTask = "ReCaptchaV2EnterpriseTask"
|
|
81
43
|
ReCaptchaV2TaskProxyLess = "ReCaptchaV2TaskProxyLess"
|
|
82
44
|
ReCaptchaV2EnterpriseTaskProxyLess = "ReCaptchaV2EnterpriseTaskProxyLess"
|
|
83
45
|
|
|
84
|
-
|
|
85
|
-
class ReCaptchaV3TypeEnm(str, MyEnum):
|
|
86
46
|
ReCaptchaV3Task = "ReCaptchaV3Task"
|
|
87
47
|
ReCaptchaV3EnterpriseTask = "ReCaptchaV3EnterpriseTask"
|
|
88
48
|
ReCaptchaV3TaskProxyLess = "ReCaptchaV3TaskProxyLess"
|
|
89
49
|
ReCaptchaV3EnterpriseTaskProxyLess = "ReCaptchaV3EnterpriseTaskProxyLess"
|
|
90
50
|
|
|
91
|
-
|
|
92
|
-
class MtCaptchaTypeEnm(str, MyEnum):
|
|
93
51
|
MtCaptchaTask = "MtCaptchaTask"
|
|
94
52
|
MtCaptchaTaskProxyLess = "MtCaptchaTaskProxyLess"
|
|
95
53
|
|
|
96
|
-
|
|
97
|
-
class DatadomeSliderTypeEnm(str, MyEnum):
|
|
98
54
|
DatadomeSliderTask = "DatadomeSliderTask"
|
|
99
55
|
|
|
100
|
-
|
|
101
|
-
class CloudflareTypeEnm(str, MyEnum):
|
|
56
|
+
AntiTurnstileTaskProxyLess = "AntiTurnstileTaskProxyLess"
|
|
102
57
|
AntiCloudflareTask = "AntiCloudflareTask"
|
|
103
58
|
|
|
59
|
+
FriendlyCaptchaTaskProxyless = "FriendlyCaptchaTaskProxyless"
|
|
60
|
+
|
|
61
|
+
YandexCaptchaTaskProxyLess = "YandexCaptchaTaskProxyLess"
|
|
104
62
|
|
|
105
|
-
class AntiAwsWafTaskTypeEnm(str, MyEnum):
|
|
106
63
|
AntiAwsWafTask = "AntiAwsWafTask"
|
|
107
64
|
AntiAwsWafTaskProxyLess = "AntiAwsWafTaskProxyLess"
|
|
65
|
+
AwsWafClassification = "AwsWafClassification"
|
|
108
66
|
|
|
109
67
|
|
|
110
|
-
class
|
|
111
|
-
AntiCyberSiAraTask = "AntiCyberSiAraTask"
|
|
112
|
-
AntiCyberSiAraTaskProxyLess = "AntiCyberSiAraTaskProxyLess"
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class AntiAkamaiTaskEnm(str, MyEnum):
|
|
116
|
-
AntiAkamaiBMPTask = "AntiAkamaiBMPTask"
|
|
117
|
-
AntiAkamaiWebTask = "AntiAkamaiWebTask"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class AntiImpervaTaskEnm(str, MyEnum):
|
|
121
|
-
AntiImpervaTask = "AntiImpervaTask"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
class BinanceCaptchaTaskEnm(str, MyEnum):
|
|
125
|
-
BinanceCaptchaTask = "BinanceCaptchaTask"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
class ResponseStatusEnm(str, MyEnum):
|
|
68
|
+
class ResponseStatusEnm(MyEnum):
|
|
129
69
|
"""
|
|
130
70
|
Enum store results `status` field variants
|
|
131
71
|
|
|
@@ -137,3 +77,8 @@ class ResponseStatusEnm(str, MyEnum):
|
|
|
137
77
|
Processing = "processing" # Task is not ready yet
|
|
138
78
|
Ready = "ready" # Task completed, solution object can be found in solution property
|
|
139
79
|
Failed = "failed" # Task failed, check the errorDescription to know why failed.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class SaveFormatsEnm(MyEnum):
|
|
83
|
+
TEMP = "temp"
|
|
84
|
+
CONST = "const"
|