2captcha-python 1.5.1__tar.gz → 2.0.0__tar.gz
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.
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0/2captcha_python.egg-info}/PKG-INFO +74 -8
- 2captcha_python-2.0.0/2captcha_python.egg-info/SOURCES.txt +16 -0
- 2captcha_python-2.0.0/2captcha_python.egg-info/requires.txt +3 -0
- 2captcha_python-1.5.1/README.md → 2captcha_python-2.0.0/PKG-INFO +102 -6
- 2captcha_python-1.5.1/2captcha_python.egg-info/PKG-INFO → 2captcha_python-2.0.0/README.md +69 -36
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/setup.py +3 -3
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/twocaptcha/__init__.py +8 -3
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/twocaptcha/api.py +8 -12
- 2captcha_python-2.0.0/twocaptcha/async_api.py +124 -0
- 2captcha_python-2.0.0/twocaptcha/async_solver.py +1120 -0
- 2captcha_python-2.0.0/twocaptcha/exceptions/__init__.py +0 -0
- 2captcha_python-2.0.0/twocaptcha/exceptions/api.py +6 -0
- 2captcha_python-2.0.0/twocaptcha/exceptions/solver.py +18 -0
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/twocaptcha/solver.py +162 -45
- 2captcha_python-1.5.1/2captcha_python.egg-info/SOURCES.txt +0 -35
- 2captcha_python-1.5.1/2captcha_python.egg-info/requires.txt +0 -1
- 2captcha_python-1.5.1/tests/test_amazon_waf.py +0 -42
- 2captcha_python-1.5.1/tests/test_atb_captcha.py +0 -31
- 2captcha_python-1.5.1/tests/test_canvas.py +0 -89
- 2captcha_python-1.5.1/tests/test_capy.py +0 -38
- 2captcha_python-1.5.1/tests/test_coordinates.py +0 -84
- 2captcha_python-1.5.1/tests/test_cutcaptcha.py +0 -31
- 2captcha_python-1.5.1/tests/test_cybersiara.py +0 -32
- 2captcha_python-1.5.1/tests/test_datadome.py +0 -34
- 2captcha_python-1.5.1/tests/test_friendly_captcha.py +0 -29
- 2captcha_python-1.5.1/tests/test_funcaptcha.py +0 -44
- 2captcha_python-1.5.1/tests/test_geetest.py +0 -41
- 2captcha_python-1.5.1/tests/test_geetest_v4.py +0 -34
- 2captcha_python-1.5.1/tests/test_grid.py +0 -91
- 2captcha_python-1.5.1/tests/test_hcaptcha.py +0 -38
- 2captcha_python-1.5.1/tests/test_keycaptcha.py +0 -44
- 2captcha_python-1.5.1/tests/test_lemin.py +0 -42
- 2captcha_python-1.5.1/tests/test_mtcaptcha.py +0 -29
- 2captcha_python-1.5.1/tests/test_normal.py +0 -102
- 2captcha_python-1.5.1/tests/test_recaptcha.py +0 -66
- 2captcha_python-1.5.1/tests/test_rotate.py +0 -109
- 2captcha_python-1.5.1/tests/test_tencent.py +0 -29
- 2captcha_python-1.5.1/tests/test_text.py +0 -40
- 2captcha_python-1.5.1/tests/test_turnstile.py +0 -36
- 2captcha_python-1.5.1/tests/test_yandex_smart_captcha.py +0 -29
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/2captcha_python.egg-info/dependency_links.txt +0 -0
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/2captcha_python.egg-info/top_level.txt +0 -0
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/LICENSE +0 -0
- {2captcha_python-1.5.1 → 2captcha_python-2.0.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: 2captcha-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Python module for easy integration with 2Captcha API
|
|
5
5
|
Home-page: https://github.com/2captcha/2captcha-python/
|
|
6
6
|
Author: 2Captcha
|
|
@@ -17,6 +17,8 @@ Requires-Python: >=3.6
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: requests
|
|
20
|
+
Requires-Dist: httpx
|
|
21
|
+
Requires-Dist: aiofiles
|
|
20
22
|
Dynamic: author
|
|
21
23
|
Dynamic: author-email
|
|
22
24
|
Dynamic: classifier
|
|
@@ -24,6 +26,7 @@ Dynamic: description
|
|
|
24
26
|
Dynamic: description-content-type
|
|
25
27
|
Dynamic: home-page
|
|
26
28
|
Dynamic: keywords
|
|
29
|
+
Dynamic: license-file
|
|
27
30
|
Dynamic: requires-dist
|
|
28
31
|
Dynamic: requires-python
|
|
29
32
|
Dynamic: summary
|
|
@@ -82,11 +85,11 @@ Examples of API requests for different captcha types are available on the [Pytho
|
|
|
82
85
|
- [Async calls](#async-calls)
|
|
83
86
|
- [Examples](#examples)
|
|
84
87
|
- [Examples using Selenium](#examples-using-selenium)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
- [Useful articles](#useful-articles)
|
|
89
|
+
- [Get in touch](#get-in-touch)
|
|
90
|
+
- [Join the team 👪](#join-the-team-)
|
|
91
|
+
- [License](#license)
|
|
92
|
+
- [Graphics and Trademarks](#graphics-and-trademarks)
|
|
90
93
|
|
|
91
94
|
## Installation
|
|
92
95
|
|
|
@@ -106,6 +109,18 @@ from twocaptcha import TwoCaptcha
|
|
|
106
109
|
|
|
107
110
|
solver = TwoCaptcha('YOUR_API_KEY')
|
|
108
111
|
```
|
|
112
|
+
|
|
113
|
+
<details>
|
|
114
|
+
<summary>Async</summary>
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
118
|
+
|
|
119
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
</details>
|
|
123
|
+
|
|
109
124
|
Also, there are a few options that can be configured:
|
|
110
125
|
|
|
111
126
|
```python
|
|
@@ -547,7 +562,55 @@ proxy={
|
|
|
547
562
|
```
|
|
548
563
|
|
|
549
564
|
## Async calls
|
|
550
|
-
|
|
565
|
+
|
|
566
|
+
To use the async version, just replace `TwoCaptcha` with `AsyncTwoCaptcha`:
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
import asyncio
|
|
570
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
571
|
+
|
|
572
|
+
async def solve_captcha():
|
|
573
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
574
|
+
|
|
575
|
+
try:
|
|
576
|
+
recaptcha_result = await solver.recaptcha(...)
|
|
577
|
+
return recaptcha_result
|
|
578
|
+
except Exception as e:
|
|
579
|
+
print(e)
|
|
580
|
+
return None
|
|
581
|
+
|
|
582
|
+
if __name__ == '__main__':
|
|
583
|
+
result = asyncio.run(solve_captcha())
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
The `AsyncTwoCaptcha` class supports all the same methods and parameters as the synchronous `TwoCaptcha` class but operates asynchronously. Configuration is identical.
|
|
587
|
+
|
|
588
|
+
### Solving Multiple Captchas in Parallel
|
|
589
|
+
|
|
590
|
+
One of the main advantages of using async support is the ability to solve multiple captchas concurrently:
|
|
591
|
+
|
|
592
|
+
```python
|
|
593
|
+
async def solve_multiple_captchas():
|
|
594
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
595
|
+
|
|
596
|
+
# Start all tasks simultaneously
|
|
597
|
+
task1 = asyncio.create_task(solver.text('What color is the sky on a clear day?'))
|
|
598
|
+
task2 = asyncio.create_task(solver.text('What is 2+2?'))
|
|
599
|
+
task3 = asyncio.create_task(solver.text('Name of the planet we live on?'))
|
|
600
|
+
|
|
601
|
+
# Wait for all tasks to complete
|
|
602
|
+
results = await asyncio.gather(task1, task2, task3, return_exceptions=True)
|
|
603
|
+
return results
|
|
604
|
+
|
|
605
|
+
# This completes much faster than solving captchas sequentially
|
|
606
|
+
results = asyncio.run(solve_multiple_captchas())
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Examples of solving all supported captcha types asynchronously are located in the [examples/async directory] directory.
|
|
610
|
+
|
|
611
|
+
### Legacy Async Method
|
|
612
|
+
|
|
613
|
+
For backward compatibility, you can also use the traditional executor-based approach with the synchronous client:
|
|
551
614
|
|
|
552
615
|
```python
|
|
553
616
|
import asyncio
|
|
@@ -565,6 +628,7 @@ async def captchaSolver(image):
|
|
|
565
628
|
|
|
566
629
|
captcha_result = asyncio.run(captchaSolver(image))
|
|
567
630
|
```
|
|
631
|
+
|
|
568
632
|
## Examples
|
|
569
633
|
Examples of solving all supported captcha types are located in the [examples] directory.
|
|
570
634
|
|
|
@@ -604,6 +668,8 @@ The graphics and trademarks included in this repository are not covered by the M
|
|
|
604
668
|
[post options]: https://2captcha.com/2captcha-api#normal_post
|
|
605
669
|
[list of supported languages]: https://2captcha.com/2captcha-api#language
|
|
606
670
|
[examples directory]: /examples
|
|
671
|
+
[examples/sync directory]: /examples/sync
|
|
672
|
+
[examples/async directory]: /examples/async
|
|
607
673
|
[asyncio]: https://docs.python.org/3/library/asyncio.html
|
|
608
674
|
[Buy residential proxies]: https://2captcha.com/proxy/residential-proxies
|
|
609
675
|
[Quick start]: https://2captcha.com/proxy?openAddTrafficModal=true
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
2captcha_python.egg-info/PKG-INFO
|
|
5
|
+
2captcha_python.egg-info/SOURCES.txt
|
|
6
|
+
2captcha_python.egg-info/dependency_links.txt
|
|
7
|
+
2captcha_python.egg-info/requires.txt
|
|
8
|
+
2captcha_python.egg-info/top_level.txt
|
|
9
|
+
twocaptcha/__init__.py
|
|
10
|
+
twocaptcha/api.py
|
|
11
|
+
twocaptcha/async_api.py
|
|
12
|
+
twocaptcha/async_solver.py
|
|
13
|
+
twocaptcha/solver.py
|
|
14
|
+
twocaptcha/exceptions/__init__.py
|
|
15
|
+
twocaptcha/exceptions/api.py
|
|
16
|
+
twocaptcha/exceptions/solver.py
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: 2captcha-python
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Python module for easy integration with 2Captcha API
|
|
5
|
+
Home-page: https://github.com/2captcha/2captcha-python/
|
|
6
|
+
Author: 2Captcha
|
|
7
|
+
Author-email: info@2captcha.com
|
|
8
|
+
Keywords: 2captcha,captcha,api,captcha solver,reCAPTCHA,FunCaptcha,Geetest,image captcha,Coordinates,Click Captcha,Geetest V4,Lemin captcha,Amazon WAF,Cloudflare Turnstile,Capy Puzzle,MTCaptcha,Friendly Captcha,Tencent,Cutcaptcha,DataDome,cybersiara
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
14
|
+
Classifier: Topic :: Utilities
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Requires-Python: >=3.6
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: requests
|
|
20
|
+
Requires-Dist: httpx
|
|
21
|
+
Requires-Dist: aiofiles
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-dist
|
|
31
|
+
Dynamic: requires-python
|
|
32
|
+
Dynamic: summary
|
|
33
|
+
|
|
1
34
|
<a href="https://github.com/2captcha/2captcha-python"><img src="https://github.com/user-attachments/assets/a737d428-5233-4605-9d09-211fa213d069" width="82" height="30"></a>
|
|
2
35
|
<a href="https://github.com/2captcha/2captcha-javascript"><img src="https://github.com/user-attachments/assets/4d3b4541-34b2-4ed2-a687-d694ce67e5a6" width="36" height="30"></a>
|
|
3
36
|
<a href="https://github.com/2captcha/2captcha-go"><img src="https://github.com/user-attachments/assets/ab22182e-6cb2-41fa-91f4-d5e89c6d7c6f" width="63" height="30"></a>
|
|
@@ -52,11 +85,11 @@ Examples of API requests for different captcha types are available on the [Pytho
|
|
|
52
85
|
- [Async calls](#async-calls)
|
|
53
86
|
- [Examples](#examples)
|
|
54
87
|
- [Examples using Selenium](#examples-using-selenium)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
88
|
+
- [Useful articles](#useful-articles)
|
|
89
|
+
- [Get in touch](#get-in-touch)
|
|
90
|
+
- [Join the team 👪](#join-the-team-)
|
|
91
|
+
- [License](#license)
|
|
92
|
+
- [Graphics and Trademarks](#graphics-and-trademarks)
|
|
60
93
|
|
|
61
94
|
## Installation
|
|
62
95
|
|
|
@@ -76,6 +109,18 @@ from twocaptcha import TwoCaptcha
|
|
|
76
109
|
|
|
77
110
|
solver = TwoCaptcha('YOUR_API_KEY')
|
|
78
111
|
```
|
|
112
|
+
|
|
113
|
+
<details>
|
|
114
|
+
<summary>Async</summary>
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
118
|
+
|
|
119
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
</details>
|
|
123
|
+
|
|
79
124
|
Also, there are a few options that can be configured:
|
|
80
125
|
|
|
81
126
|
```python
|
|
@@ -517,7 +562,55 @@ proxy={
|
|
|
517
562
|
```
|
|
518
563
|
|
|
519
564
|
## Async calls
|
|
520
|
-
|
|
565
|
+
|
|
566
|
+
To use the async version, just replace `TwoCaptcha` with `AsyncTwoCaptcha`:
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
import asyncio
|
|
570
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
571
|
+
|
|
572
|
+
async def solve_captcha():
|
|
573
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
574
|
+
|
|
575
|
+
try:
|
|
576
|
+
recaptcha_result = await solver.recaptcha(...)
|
|
577
|
+
return recaptcha_result
|
|
578
|
+
except Exception as e:
|
|
579
|
+
print(e)
|
|
580
|
+
return None
|
|
581
|
+
|
|
582
|
+
if __name__ == '__main__':
|
|
583
|
+
result = asyncio.run(solve_captcha())
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
The `AsyncTwoCaptcha` class supports all the same methods and parameters as the synchronous `TwoCaptcha` class but operates asynchronously. Configuration is identical.
|
|
587
|
+
|
|
588
|
+
### Solving Multiple Captchas in Parallel
|
|
589
|
+
|
|
590
|
+
One of the main advantages of using async support is the ability to solve multiple captchas concurrently:
|
|
591
|
+
|
|
592
|
+
```python
|
|
593
|
+
async def solve_multiple_captchas():
|
|
594
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
595
|
+
|
|
596
|
+
# Start all tasks simultaneously
|
|
597
|
+
task1 = asyncio.create_task(solver.text('What color is the sky on a clear day?'))
|
|
598
|
+
task2 = asyncio.create_task(solver.text('What is 2+2?'))
|
|
599
|
+
task3 = asyncio.create_task(solver.text('Name of the planet we live on?'))
|
|
600
|
+
|
|
601
|
+
# Wait for all tasks to complete
|
|
602
|
+
results = await asyncio.gather(task1, task2, task3, return_exceptions=True)
|
|
603
|
+
return results
|
|
604
|
+
|
|
605
|
+
# This completes much faster than solving captchas sequentially
|
|
606
|
+
results = asyncio.run(solve_multiple_captchas())
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Examples of solving all supported captcha types asynchronously are located in the [examples/async directory] directory.
|
|
610
|
+
|
|
611
|
+
### Legacy Async Method
|
|
612
|
+
|
|
613
|
+
For backward compatibility, you can also use the traditional executor-based approach with the synchronous client:
|
|
521
614
|
|
|
522
615
|
```python
|
|
523
616
|
import asyncio
|
|
@@ -535,6 +628,7 @@ async def captchaSolver(image):
|
|
|
535
628
|
|
|
536
629
|
captcha_result = asyncio.run(captchaSolver(image))
|
|
537
630
|
```
|
|
631
|
+
|
|
538
632
|
## Examples
|
|
539
633
|
Examples of solving all supported captcha types are located in the [examples] directory.
|
|
540
634
|
|
|
@@ -574,6 +668,8 @@ The graphics and trademarks included in this repository are not covered by the M
|
|
|
574
668
|
[post options]: https://2captcha.com/2captcha-api#normal_post
|
|
575
669
|
[list of supported languages]: https://2captcha.com/2captcha-api#language
|
|
576
670
|
[examples directory]: /examples
|
|
671
|
+
[examples/sync directory]: /examples/sync
|
|
672
|
+
[examples/async directory]: /examples/async
|
|
577
673
|
[asyncio]: https://docs.python.org/3/library/asyncio.html
|
|
578
674
|
[Buy residential proxies]: https://2captcha.com/proxy/residential-proxies
|
|
579
675
|
[Quick start]: https://2captcha.com/proxy?openAddTrafficModal=true
|
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.2
|
|
2
|
-
Name: 2captcha-python
|
|
3
|
-
Version: 1.5.1
|
|
4
|
-
Summary: Python module for easy integration with 2Captcha API
|
|
5
|
-
Home-page: https://github.com/2captcha/2captcha-python/
|
|
6
|
-
Author: 2Captcha
|
|
7
|
-
Author-email: info@2captcha.com
|
|
8
|
-
Keywords: 2captcha,captcha,api,captcha solver,reCAPTCHA,FunCaptcha,Geetest,image captcha,Coordinates,Click Captcha,Geetest V4,Lemin captcha,Amazon WAF,Cloudflare Turnstile,Capy Puzzle,MTCaptcha,Friendly Captcha,Tencent,Cutcaptcha,DataDome,cybersiara
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
-
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
14
|
-
Classifier: Topic :: Utilities
|
|
15
|
-
Classifier: Intended Audience :: Developers
|
|
16
|
-
Requires-Python: >=3.6
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
Requires-Dist: requests
|
|
20
|
-
Dynamic: author
|
|
21
|
-
Dynamic: author-email
|
|
22
|
-
Dynamic: classifier
|
|
23
|
-
Dynamic: description
|
|
24
|
-
Dynamic: description-content-type
|
|
25
|
-
Dynamic: home-page
|
|
26
|
-
Dynamic: keywords
|
|
27
|
-
Dynamic: requires-dist
|
|
28
|
-
Dynamic: requires-python
|
|
29
|
-
Dynamic: summary
|
|
30
|
-
|
|
31
1
|
<a href="https://github.com/2captcha/2captcha-python"><img src="https://github.com/user-attachments/assets/a737d428-5233-4605-9d09-211fa213d069" width="82" height="30"></a>
|
|
32
2
|
<a href="https://github.com/2captcha/2captcha-javascript"><img src="https://github.com/user-attachments/assets/4d3b4541-34b2-4ed2-a687-d694ce67e5a6" width="36" height="30"></a>
|
|
33
3
|
<a href="https://github.com/2captcha/2captcha-go"><img src="https://github.com/user-attachments/assets/ab22182e-6cb2-41fa-91f4-d5e89c6d7c6f" width="63" height="30"></a>
|
|
@@ -82,11 +52,11 @@ Examples of API requests for different captcha types are available on the [Pytho
|
|
|
82
52
|
- [Async calls](#async-calls)
|
|
83
53
|
- [Examples](#examples)
|
|
84
54
|
- [Examples using Selenium](#examples-using-selenium)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
55
|
+
- [Useful articles](#useful-articles)
|
|
56
|
+
- [Get in touch](#get-in-touch)
|
|
57
|
+
- [Join the team 👪](#join-the-team-)
|
|
58
|
+
- [License](#license)
|
|
59
|
+
- [Graphics and Trademarks](#graphics-and-trademarks)
|
|
90
60
|
|
|
91
61
|
## Installation
|
|
92
62
|
|
|
@@ -106,6 +76,18 @@ from twocaptcha import TwoCaptcha
|
|
|
106
76
|
|
|
107
77
|
solver = TwoCaptcha('YOUR_API_KEY')
|
|
108
78
|
```
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary>Async</summary>
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
85
|
+
|
|
86
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
</details>
|
|
90
|
+
|
|
109
91
|
Also, there are a few options that can be configured:
|
|
110
92
|
|
|
111
93
|
```python
|
|
@@ -547,7 +529,55 @@ proxy={
|
|
|
547
529
|
```
|
|
548
530
|
|
|
549
531
|
## Async calls
|
|
550
|
-
|
|
532
|
+
|
|
533
|
+
To use the async version, just replace `TwoCaptcha` with `AsyncTwoCaptcha`:
|
|
534
|
+
|
|
535
|
+
```python
|
|
536
|
+
import asyncio
|
|
537
|
+
from twocaptcha import AsyncTwoCaptcha
|
|
538
|
+
|
|
539
|
+
async def solve_captcha():
|
|
540
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
541
|
+
|
|
542
|
+
try:
|
|
543
|
+
recaptcha_result = await solver.recaptcha(...)
|
|
544
|
+
return recaptcha_result
|
|
545
|
+
except Exception as e:
|
|
546
|
+
print(e)
|
|
547
|
+
return None
|
|
548
|
+
|
|
549
|
+
if __name__ == '__main__':
|
|
550
|
+
result = asyncio.run(solve_captcha())
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
The `AsyncTwoCaptcha` class supports all the same methods and parameters as the synchronous `TwoCaptcha` class but operates asynchronously. Configuration is identical.
|
|
554
|
+
|
|
555
|
+
### Solving Multiple Captchas in Parallel
|
|
556
|
+
|
|
557
|
+
One of the main advantages of using async support is the ability to solve multiple captchas concurrently:
|
|
558
|
+
|
|
559
|
+
```python
|
|
560
|
+
async def solve_multiple_captchas():
|
|
561
|
+
solver = AsyncTwoCaptcha('YOUR_API_KEY')
|
|
562
|
+
|
|
563
|
+
# Start all tasks simultaneously
|
|
564
|
+
task1 = asyncio.create_task(solver.text('What color is the sky on a clear day?'))
|
|
565
|
+
task2 = asyncio.create_task(solver.text('What is 2+2?'))
|
|
566
|
+
task3 = asyncio.create_task(solver.text('Name of the planet we live on?'))
|
|
567
|
+
|
|
568
|
+
# Wait for all tasks to complete
|
|
569
|
+
results = await asyncio.gather(task1, task2, task3, return_exceptions=True)
|
|
570
|
+
return results
|
|
571
|
+
|
|
572
|
+
# This completes much faster than solving captchas sequentially
|
|
573
|
+
results = asyncio.run(solve_multiple_captchas())
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Examples of solving all supported captcha types asynchronously are located in the [examples/async directory] directory.
|
|
577
|
+
|
|
578
|
+
### Legacy Async Method
|
|
579
|
+
|
|
580
|
+
For backward compatibility, you can also use the traditional executor-based approach with the synchronous client:
|
|
551
581
|
|
|
552
582
|
```python
|
|
553
583
|
import asyncio
|
|
@@ -565,6 +595,7 @@ async def captchaSolver(image):
|
|
|
565
595
|
|
|
566
596
|
captcha_result = asyncio.run(captchaSolver(image))
|
|
567
597
|
```
|
|
598
|
+
|
|
568
599
|
## Examples
|
|
569
600
|
Examples of solving all supported captcha types are located in the [examples] directory.
|
|
570
601
|
|
|
@@ -604,6 +635,8 @@ The graphics and trademarks included in this repository are not covered by the M
|
|
|
604
635
|
[post options]: https://2captcha.com/2captcha-api#normal_post
|
|
605
636
|
[list of supported languages]: https://2captcha.com/2captcha-api#language
|
|
606
637
|
[examples directory]: /examples
|
|
638
|
+
[examples/sync directory]: /examples/sync
|
|
639
|
+
[examples/async directory]: /examples/async
|
|
607
640
|
[asyncio]: https://docs.python.org/3/library/asyncio.html
|
|
608
641
|
[Buy residential proxies]: https://2captcha.com/proxy/residential-proxies
|
|
609
642
|
[Quick start]: https://2captcha.com/proxy?openAddTrafficModal=true
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
from setuptools import setup, find_packages
|
|
4
4
|
import re
|
|
5
5
|
|
|
6
|
-
with open("README.md", "r") as fh:
|
|
6
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
7
7
|
long_description = fh.read()
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def get_version():
|
|
11
|
-
with open('twocaptcha/__init__.py', 'r') as f:
|
|
11
|
+
with open('twocaptcha/__init__.py', 'r', encoding="utf-8") as f:
|
|
12
12
|
return re.search(r'__version__ = ["\'](.*?)["\']', f.read()).group(1)
|
|
13
13
|
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ setup(name='2captcha-python',
|
|
|
18
18
|
long_description=long_description,
|
|
19
19
|
long_description_content_type="text/markdown",
|
|
20
20
|
url='https://github.com/2captcha/2captcha-python/',
|
|
21
|
-
install_requires=['requests'],
|
|
21
|
+
install_requires=['requests', 'httpx', 'aiofiles'],
|
|
22
22
|
author='2Captcha',
|
|
23
23
|
author_email='info@2captcha.com',
|
|
24
24
|
packages=find_packages(),
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
from .api import ApiClient
|
|
2
|
-
from .solver import
|
|
3
|
-
|
|
2
|
+
from .solver import TwoCaptcha
|
|
3
|
+
|
|
4
|
+
from .async_api import AsyncApiClient
|
|
5
|
+
from .async_solver import AsyncTwoCaptcha
|
|
6
|
+
|
|
7
|
+
from .solver import SolverExceptions, ValidationException, NetworkException, ApiException, TimeoutException
|
|
8
|
+
|
|
4
9
|
|
|
5
10
|
"""
|
|
6
11
|
Python 3 package for easy integration with the API of 2captcha captcha solving service to bypass recaptcha,
|
|
@@ -12,4 +17,4 @@ support@2captcha.com
|
|
|
12
17
|
"""
|
|
13
18
|
|
|
14
19
|
__author__ = '2captcha'
|
|
15
|
-
__version__ = '
|
|
20
|
+
__version__ = '2.0.0'
|
|
@@ -2,20 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import requests
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ApiException(Exception):
|
|
11
|
-
pass
|
|
5
|
+
try:
|
|
6
|
+
from .exceptions.api import NetworkException, ApiException
|
|
7
|
+
except ImportError:
|
|
8
|
+
from twocaptcha.exceptions.api import NetworkException, ApiException
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
class ApiClient():
|
|
15
|
-
def __init__(self, post_url
|
|
12
|
+
def __init__(self, post_url='2captcha.com'):
|
|
16
13
|
self.post_url = post_url
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
|
|
19
15
|
def in_(self, files={}, **kwargs):
|
|
20
16
|
'''
|
|
21
17
|
|
|
@@ -43,7 +39,7 @@ class ApiClient():
|
|
|
43
39
|
'''
|
|
44
40
|
|
|
45
41
|
try:
|
|
46
|
-
current_url = 'https://'+self.post_url+'/in.php'
|
|
42
|
+
current_url = 'https://' + self.post_url + '/in.php'
|
|
47
43
|
if files:
|
|
48
44
|
|
|
49
45
|
files = {key: open(path, 'rb') for key, path in files.items()}
|
|
@@ -101,7 +97,7 @@ class ApiClient():
|
|
|
101
97
|
'''
|
|
102
98
|
|
|
103
99
|
try:
|
|
104
|
-
current_url_out = 'https://'+self.post_url+'/res.php'
|
|
100
|
+
current_url_out = 'https://' + self.post_url + '/res.php'
|
|
105
101
|
resp = requests.get(current_url_out, params=kwargs)
|
|
106
102
|
|
|
107
103
|
if resp.status_code != 200:
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
from contextlib import AsyncExitStack
|
|
4
|
+
|
|
5
|
+
import aiofiles
|
|
6
|
+
import httpx
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from .exceptions.api import NetworkException, ApiException
|
|
10
|
+
except ImportError:
|
|
11
|
+
from twocaptcha.exceptions.api import NetworkException, ApiException
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AsyncApiClient():
|
|
15
|
+
def __init__(self, post_url='2captcha.com'):
|
|
16
|
+
self.post_url = post_url
|
|
17
|
+
|
|
18
|
+
async def in_(self, files={}, **kwargs):
|
|
19
|
+
'''
|
|
20
|
+
|
|
21
|
+
sends POST-request (files and/or params) to solve captcha
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
files : TYPE, optional
|
|
26
|
+
DESCRIPTION. The default is {}.
|
|
27
|
+
**kwargs : TYPE
|
|
28
|
+
DESCRIPTION.
|
|
29
|
+
|
|
30
|
+
Raises
|
|
31
|
+
------
|
|
32
|
+
NetworkException
|
|
33
|
+
DESCRIPTION.
|
|
34
|
+
ApiException
|
|
35
|
+
DESCRIPTION.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
resp : TYPE
|
|
40
|
+
DESCRIPTION.
|
|
41
|
+
|
|
42
|
+
'''
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
current_url = 'https://' + self.post_url + '/in.php'
|
|
46
|
+
|
|
47
|
+
async with httpx.AsyncClient(follow_redirects=True) as client:
|
|
48
|
+
if files:
|
|
49
|
+
async with AsyncExitStack() as stack:
|
|
50
|
+
file_objects = {}
|
|
51
|
+
for key, path in files.items():
|
|
52
|
+
file_handle = await stack.enter_async_context(aiofiles.open(path, 'rb'))
|
|
53
|
+
content = await file_handle.read()
|
|
54
|
+
file_objects[key] = content
|
|
55
|
+
|
|
56
|
+
resp = await client.post(current_url,
|
|
57
|
+
data=kwargs,
|
|
58
|
+
files=file_objects)
|
|
59
|
+
|
|
60
|
+
elif 'file' in kwargs:
|
|
61
|
+
file_path = kwargs.pop('file')
|
|
62
|
+
async with aiofiles.open(file_path, 'rb') as file_handle:
|
|
63
|
+
content = await file_handle.read()
|
|
64
|
+
resp = await client.post(current_url,
|
|
65
|
+
data=kwargs,
|
|
66
|
+
files={'file': content})
|
|
67
|
+
else:
|
|
68
|
+
resp = await client.post(current_url,
|
|
69
|
+
data=kwargs)
|
|
70
|
+
|
|
71
|
+
except httpx.RequestError as e:
|
|
72
|
+
raise NetworkException(e)
|
|
73
|
+
|
|
74
|
+
if resp.status_code != 200:
|
|
75
|
+
raise NetworkException(f'bad response: {resp.status_code}')
|
|
76
|
+
|
|
77
|
+
resp = resp.content.decode('utf-8')
|
|
78
|
+
|
|
79
|
+
if 'ERROR' in resp:
|
|
80
|
+
raise ApiException(resp)
|
|
81
|
+
|
|
82
|
+
return resp
|
|
83
|
+
|
|
84
|
+
async def res(self, **kwargs):
|
|
85
|
+
'''
|
|
86
|
+
sends additional GET-requests (solved captcha, balance, report etc.)
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
**kwargs : TYPE
|
|
91
|
+
DESCRIPTION.
|
|
92
|
+
|
|
93
|
+
Raises
|
|
94
|
+
------
|
|
95
|
+
NetworkException
|
|
96
|
+
DESCRIPTION.
|
|
97
|
+
ApiException
|
|
98
|
+
DESCRIPTION.
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
resp : TYPE
|
|
103
|
+
DESCRIPTION.
|
|
104
|
+
|
|
105
|
+
'''
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
current_url_out = 'https://' + self.post_url + '/res.php'
|
|
109
|
+
|
|
110
|
+
async with httpx.AsyncClient(follow_redirects=True) as client:
|
|
111
|
+
resp = await client.get(current_url_out, params=kwargs)
|
|
112
|
+
|
|
113
|
+
if resp.status_code != 200:
|
|
114
|
+
raise NetworkException(f'bad response: {resp.status_code}')
|
|
115
|
+
|
|
116
|
+
resp = resp.content.decode('utf-8')
|
|
117
|
+
|
|
118
|
+
if 'ERROR' in resp:
|
|
119
|
+
raise ApiException(resp)
|
|
120
|
+
|
|
121
|
+
except httpx.RequestError as e:
|
|
122
|
+
raise NetworkException(e)
|
|
123
|
+
|
|
124
|
+
return resp
|