python-anticaptcha 1.0.0__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.
- python_anticaptcha-2.0.0/.github/workflows/e2e.yml +33 -0
- python_anticaptcha-2.0.0/.github/workflows/publish.yml +70 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/.github/workflows/pythonpackage.yml +19 -11
- python_anticaptcha-2.0.0/.pre-commit-config.yaml +16 -0
- python_anticaptcha-2.0.0/.readthedocs.yaml +19 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/CHANGELOG.rst +41 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/CODE_OF_CONDUCT.md +1 -1
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/Makefile +16 -9
- python_anticaptcha-2.0.0/PKG-INFO +277 -0
- python_anticaptcha-2.0.0/README.md +243 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/docs/api.rst +10 -3
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/docs/conf.py +18 -19
- python_anticaptcha-2.0.0/docs/development.rst +18 -0
- python_anticaptcha-2.0.0/docs/index.rst +35 -0
- python_anticaptcha-2.0.0/docs/usage.rst +218 -0
- python_anticaptcha-2.0.0/examples/async_balance.py +17 -0
- python_anticaptcha-2.0.0/examples/async_recaptcha_request.py +40 -0
- python-anticaptcha-1.0.0/examples/antigate.py → python_anticaptcha-2.0.0/examples/sync_antigate.py +3 -4
- python-anticaptcha-1.0.0/examples/app_stat.py → python_anticaptcha-2.0.0/examples/sync_app_stat.py +3 -2
- python-anticaptcha-1.0.0/examples/balance.py → python_anticaptcha-2.0.0/examples/sync_balance.py +3 -3
- python-anticaptcha-1.0.0/examples/funcaptcha_request.py → python_anticaptcha-2.0.0/examples/sync_funcaptcha_request.py +6 -5
- python-anticaptcha-1.0.0/examples/funcaptcha_selenium.py → python_anticaptcha-2.0.0/examples/sync_funcaptcha_selenium.py +5 -8
- python-anticaptcha-1.0.0/examples/funcaptcha_selenium_callback.py → python_anticaptcha-2.0.0/examples/sync_funcaptcha_selenium_callback.py +9 -8
- python-anticaptcha-1.0.0/examples/hcaptcha_request.py → python_anticaptcha-2.0.0/examples/sync_hcaptcha_request.py +3 -2
- python-anticaptcha-1.0.0/examples/hcaptcha_request_proxy.py → python_anticaptcha-2.0.0/examples/sync_hcaptcha_request_proxy.py +4 -4
- python-anticaptcha-1.0.0/examples/recaptcha3_request.py → python_anticaptcha-2.0.0/examples/sync_recaptcha3_request.py +7 -5
- python-anticaptcha-1.0.0/examples/recaptcha_request.py → python_anticaptcha-2.0.0/examples/sync_recaptcha_request.py +3 -2
- python-anticaptcha-1.0.0/examples/recaptcha_selenium.py → python_anticaptcha-2.0.0/examples/sync_recaptcha_selenium.py +4 -6
- python-anticaptcha-1.0.0/examples/recaptcha_selenium_callback.py → python_anticaptcha-2.0.0/examples/sync_recaptcha_selenium_callback.py +6 -6
- python-anticaptcha-1.0.0/examples/remote_image.py → python_anticaptcha-2.0.0/examples/sync_remote_image.py +3 -2
- python-anticaptcha-1.0.0/examples/text.py → python_anticaptcha-2.0.0/examples/sync_text.py +1 -1
- python-anticaptcha-1.0.0/examples/text_stream.py → python_anticaptcha-2.0.0/examples/sync_text_stream.py +2 -2
- python_anticaptcha-2.0.0/pyproject.toml +66 -0
- python_anticaptcha-2.0.0/python_anticaptcha/__init__.py +86 -0
- python_anticaptcha-2.0.0/python_anticaptcha/async_client.py +364 -0
- python_anticaptcha-2.0.0/python_anticaptcha/base.py +2 -0
- python_anticaptcha-2.0.0/python_anticaptcha/exceptions.py +57 -0
- python_anticaptcha-2.0.0/python_anticaptcha/proxy.py +67 -0
- python_anticaptcha-2.0.0/python_anticaptcha/sync_client.py +402 -0
- python_anticaptcha-2.0.0/python_anticaptcha/tasks.py +607 -0
- python_anticaptcha-2.0.0/tests/__init__.py +0 -0
- python_anticaptcha-2.0.0/tests/test_async_client.py +293 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/tests/test_examples.py +33 -32
- python_anticaptcha-2.0.0/tests/test_exceptions.py +42 -0
- python_anticaptcha-2.0.0/tests/test_proxy.py +69 -0
- python_anticaptcha-2.0.0/tests/test_sync_client.py +324 -0
- python_anticaptcha-2.0.0/tests/test_tasks.py +376 -0
- python_anticaptcha-2.0.0/tox.ini +22 -0
- python-anticaptcha-1.0.0/.github/workflows/e2e.yml +0 -30
- python-anticaptcha-1.0.0/.github/workflows/publish.yml +0 -35
- python-anticaptcha-1.0.0/PKG-INFO +0 -249
- python-anticaptcha-1.0.0/README.rst +0 -223
- python-anticaptcha-1.0.0/docs/development.rst +0 -19
- python-anticaptcha-1.0.0/docs/index.rst +0 -27
- python-anticaptcha-1.0.0/docs/usage.rst +0 -6
- python-anticaptcha-1.0.0/python_anticaptcha/__init__.py +0 -29
- python-anticaptcha-1.0.0/python_anticaptcha/base.py +0 -219
- python-anticaptcha-1.0.0/python_anticaptcha/compat.py +0 -15
- python-anticaptcha-1.0.0/python_anticaptcha/exceptions.py +0 -29
- python-anticaptcha-1.0.0/python_anticaptcha/tasks.py +0 -322
- python-anticaptcha-1.0.0/python_anticaptcha.egg-info/PKG-INFO +0 -249
- python-anticaptcha-1.0.0/python_anticaptcha.egg-info/SOURCES.txt +0 -54
- python-anticaptcha-1.0.0/python_anticaptcha.egg-info/dependency_links.txt +0 -1
- python-anticaptcha-1.0.0/python_anticaptcha.egg-info/requires.txt +0 -10
- python-anticaptcha-1.0.0/python_anticaptcha.egg-info/top_level.txt +0 -1
- python-anticaptcha-1.0.0/setup.cfg +0 -16
- python-anticaptcha-1.0.0/setup.py +0 -48
- python-anticaptcha-1.0.0/tox.ini +0 -12
- python-anticaptcha-1.0.0/unittest.cfg +0 -7
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/.dockerignore +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/.gitignore +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/Dockerfile.docs +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/LICENSE.md +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/docs/Makefile +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/docs/_static/.gitkeep +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/docs/changes.rst +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/examples/__init__.py +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/examples/callback_sniffer.js +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/examples/captcha_ms.jpeg +0 -0
- {python-anticaptcha-1.0.0 → python_anticaptcha-2.0.0}/examples/dot.png +0 -0
- /python-anticaptcha-1.0.0/tests/__init__.py → /python_anticaptcha-2.0.0/python_anticaptcha/py.typed +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: E2E test ↔️
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
repository_dispatch:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: 0 12 * * *
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 30
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python 3.12
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install setup dependencies
|
|
22
|
+
run: pip install setuptools_scm wheel
|
|
23
|
+
|
|
24
|
+
- name: Build distribution
|
|
25
|
+
run: make install
|
|
26
|
+
|
|
27
|
+
- uses: nanasess/setup-chromedriver@v2
|
|
28
|
+
|
|
29
|
+
- name: Run integration tests
|
|
30
|
+
run: make test_e2e
|
|
31
|
+
env:
|
|
32
|
+
ANTICAPTCHA_API_KEY: ${{ secrets.anticaptcha_key }}
|
|
33
|
+
PROXY_URL: "${{ secrets.proxy_url }}"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Publish Python package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
|
|
20
|
+
- name: Install build dependencies
|
|
21
|
+
run: pip install setuptools setuptools_scm wheel build
|
|
22
|
+
|
|
23
|
+
- name: Build distribution
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Store distribution packages
|
|
27
|
+
uses: actions/upload-artifact@v4
|
|
28
|
+
with:
|
|
29
|
+
name: python-package-distributions
|
|
30
|
+
path: dist/
|
|
31
|
+
|
|
32
|
+
publish-to-pypi:
|
|
33
|
+
name: Publish to PyPI
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
environment:
|
|
37
|
+
name: pypi
|
|
38
|
+
url: https://pypi.org/p/python-anticaptcha
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download distribution packages
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: python-package-distributions
|
|
46
|
+
path: dist/
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
50
|
+
|
|
51
|
+
publish-to-testpypi:
|
|
52
|
+
name: Publish to TestPyPI
|
|
53
|
+
needs: build
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
environment:
|
|
56
|
+
name: testpypi
|
|
57
|
+
url: https://test.pypi.org/p/python-anticaptcha
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write
|
|
60
|
+
steps:
|
|
61
|
+
- name: Download distribution packages
|
|
62
|
+
uses: actions/download-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: python-package-distributions
|
|
65
|
+
path: dist/
|
|
66
|
+
|
|
67
|
+
- name: Publish to TestPyPI
|
|
68
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
69
|
+
with:
|
|
70
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -3,6 +3,18 @@ name: Python package
|
|
|
3
3
|
on: [push]
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
|
+
lint:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@v4
|
|
10
|
+
|
|
11
|
+
- name: Set up Python
|
|
12
|
+
uses: actions/setup-python@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: '3.12'
|
|
15
|
+
|
|
16
|
+
- uses: j178/prek-action@v1
|
|
17
|
+
|
|
6
18
|
test:
|
|
7
19
|
runs-on: ubuntu-latest
|
|
8
20
|
|
|
@@ -11,19 +23,18 @@ jobs:
|
|
|
11
23
|
fail-fast: false
|
|
12
24
|
matrix:
|
|
13
25
|
python-version:
|
|
14
|
-
- '2.7'
|
|
15
|
-
- '3.5'
|
|
16
|
-
- '3.6'
|
|
17
|
-
- '3.7'
|
|
18
|
-
- '3.8'
|
|
19
26
|
- '3.9'
|
|
20
27
|
- '3.10'
|
|
28
|
+
- '3.11'
|
|
29
|
+
- '3.12'
|
|
30
|
+
- '3.13'
|
|
31
|
+
- '3.14'
|
|
21
32
|
|
|
22
33
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
34
|
+
- uses: actions/checkout@v4
|
|
24
35
|
|
|
25
36
|
- name: Set up Python ${{ matrix.python-version }}
|
|
26
|
-
uses: actions/setup-python@
|
|
37
|
+
uses: actions/setup-python@v5
|
|
27
38
|
with:
|
|
28
39
|
python-version: ${{ matrix.python-version }}
|
|
29
40
|
|
|
@@ -36,8 +47,5 @@ jobs:
|
|
|
36
47
|
- name: Build docs
|
|
37
48
|
run: make docs
|
|
38
49
|
|
|
39
|
-
- name: Build docs
|
|
40
|
-
run: make docs
|
|
41
|
-
|
|
42
50
|
- name: Test with pytest
|
|
43
|
-
run: make test
|
|
51
|
+
run: make test
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.9.10
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
10
|
+
rev: v1.15.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
additional_dependencies: [types-requests>=2.31]
|
|
14
|
+
files: ^python_anticaptcha/
|
|
15
|
+
pass_filenames: false
|
|
16
|
+
args: [python_anticaptcha]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-24.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.12"
|
|
10
|
+
|
|
11
|
+
sphinx:
|
|
12
|
+
configuration: docs/conf.py
|
|
13
|
+
|
|
14
|
+
python:
|
|
15
|
+
install:
|
|
16
|
+
- method: pip
|
|
17
|
+
path: .
|
|
18
|
+
extra_requirements:
|
|
19
|
+
- docs
|
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
2.0.0 - 2025-05-09
|
|
5
|
+
------------------
|
|
6
|
+
|
|
7
|
+
Added
|
|
8
|
+
#####
|
|
9
|
+
|
|
10
|
+
- Add ``AsyncAnticaptchaClient`` and ``AsyncJob`` for async/await usage with ``httpx`` (``pip install python-anticaptcha[async]``)
|
|
11
|
+
- Rename ``base.py`` → ``sync_client.py`` for symmetry with ``async_client.py``; backward-compatible ``base.py`` shim preserved
|
|
12
|
+
- Rename sync example files with ``sync_`` prefix to match ``async_`` examples
|
|
13
|
+
- Add context manager support to ``AnticaptchaClient`` (``__enter__``, ``__exit__``, ``close``)
|
|
14
|
+
- Add ``ANTICAPTCHA_API_KEY`` environment variable fallback for ``AnticaptchaClient``
|
|
15
|
+
- Add ``Proxy`` frozen dataclass with ``parse_url()`` and ``to_kwargs()`` methods
|
|
16
|
+
- Add snake_case aliases: ``create_task``, ``create_task_smee``, ``get_balance``, ``get_app_stats``
|
|
17
|
+
- Add ``py.typed`` marker and complete type annotations (`#124 <https://github.com/ad-m/python-anticaptcha/pull/124>`_)
|
|
18
|
+
- Add ``__repr__`` to ``Job``, ``AnticaptchaClient``, and ``BaseTask`` (`#123 <https://github.com/ad-m/python-anticaptcha/pull/123>`_)
|
|
19
|
+
- Add optional ``on_check`` callback to ``Job.join()`` (`#125 <https://github.com/ad-m/python-anticaptcha/pull/125>`_)
|
|
20
|
+
- ``ImageToTextTask`` now accepts file paths (``str``/``Path``), raw bytes, or file-like objects
|
|
21
|
+
|
|
22
|
+
Changed
|
|
23
|
+
#######
|
|
24
|
+
|
|
25
|
+
- **Breaking:** Minimum Python version increased from 2.7+ to 3.9+
|
|
26
|
+
- Migrate from ``setup.py`` / ``setup.cfg`` to ``pyproject.toml`` (PEP 621) (`#122 <https://github.com/ad-m/python-anticaptcha/pull/122>`_)
|
|
27
|
+
- Switch README from RST to Markdown (`#126 <https://github.com/ad-m/python-anticaptcha/pull/126>`_)
|
|
28
|
+
- Switch test runner from nose2 to pytest
|
|
29
|
+
- Switch PyPI publishing to trusted publishing via GitHub Actions (`#114 <https://github.com/ad-m/python-anticaptcha/pull/114>`_)
|
|
30
|
+
- Fix ``RecaptchaV2EnterpriseTask`` missing proxyless base class inheritance
|
|
31
|
+
- Fix ``ImageToTextTask.serialize()`` sending ``None`` values
|
|
32
|
+
- Fix ``GeeTestTask`` incorrect inheritance
|
|
33
|
+
- Fix ``AntiGateTaskProxyless`` super() call
|
|
34
|
+
- Remove redundant cookies serialization in ``ProxyMixin``
|
|
35
|
+
- Use Python 3 ``super()`` without arguments throughout codebase
|
|
36
|
+
|
|
37
|
+
Removed
|
|
38
|
+
#######
|
|
39
|
+
|
|
40
|
+
- **Breaking:** Drop Python 2.7 and Python 3.4-3.8 support
|
|
41
|
+
- Remove ``six`` dependency (replaced with stdlib ``urllib.parse``)
|
|
42
|
+
- Remove ``compat.py`` module
|
|
43
|
+
- Remove legacy ``setup.py`` and ``setup.cfg``
|
|
44
|
+
|
|
4
45
|
1.0.0 - 2022-03-28
|
|
5
46
|
------------------
|
|
6
47
|
|
|
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
|
|
34
34
|
|
|
35
35
|
## Enforcement
|
|
36
36
|
|
|
37
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at naczelnik@
|
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at naczelnik@jawne.info.pl. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
|
38
38
|
|
|
39
39
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
|
40
40
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
CHROMEDRIVER_VERSION=99.0.4844.17
|
|
2
|
-
CHROMEDRIVER_DIR=${PWD}/
|
|
2
|
+
CHROMEDRIVER_DIR=${PWD}/chromedriver
|
|
3
3
|
|
|
4
|
-
.PHONY: lint fmt build docs install test
|
|
4
|
+
.PHONY: lint fmt typecheck build docs install test test_e2e chromedriver
|
|
5
5
|
|
|
6
6
|
build:
|
|
7
|
-
python
|
|
7
|
+
python -m build
|
|
8
8
|
|
|
9
9
|
install: install_test install_docs install_pkg
|
|
10
10
|
|
|
@@ -18,24 +18,31 @@ install_pkg:
|
|
|
18
18
|
python -m pip install --upgrade pip wheel
|
|
19
19
|
pip install .
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
chromedriver:
|
|
22
22
|
mkdir -p ${CHROMEDRIVER_DIR}
|
|
23
23
|
wget -q -P ${CHROMEDRIVER_DIR} "http://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip"
|
|
24
24
|
unzip ${CHROMEDRIVER_DIR}/chromedriver* -d ${CHROMEDRIVER_DIR}
|
|
25
25
|
rm ${CHROMEDRIVER_DIR}/chromedriver_linux64.zip
|
|
26
26
|
|
|
27
27
|
test:
|
|
28
|
-
|
|
28
|
+
pytest
|
|
29
|
+
|
|
30
|
+
test_e2e:
|
|
31
|
+
PATH=$$PWD/chromedriver:$$PATH pytest -m e2e --override-ini="addopts="
|
|
29
32
|
|
|
30
33
|
clean:
|
|
31
|
-
rm -r build
|
|
34
|
+
rm -r build chromedriver
|
|
32
35
|
|
|
33
36
|
lint:
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
ruff check .
|
|
38
|
+
ruff format --check .
|
|
36
39
|
|
|
37
40
|
fmt:
|
|
38
|
-
|
|
41
|
+
ruff check --fix .
|
|
42
|
+
ruff format .
|
|
43
|
+
|
|
44
|
+
typecheck:
|
|
45
|
+
mypy python_anticaptcha
|
|
39
46
|
|
|
40
47
|
docs:
|
|
41
48
|
sphinx-build -W docs /dev/shm/sphinx
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-anticaptcha
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Client library for solve captchas with Anticaptcha.com support.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ad-m/python-anticaptcha
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE.md
|
|
8
|
+
Keywords: async,asyncio,captcha,development,httpx,recaptcha
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Framework :: AsyncIO
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Requires-Dist: requests
|
|
22
|
+
Provides-Extra: async
|
|
23
|
+
Requires-Dist: httpx>=0.24; extra == 'async'
|
|
24
|
+
Provides-Extra: docs
|
|
25
|
+
Requires-Dist: sphinx; extra == 'docs'
|
|
26
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
|
|
27
|
+
Provides-Extra: tests
|
|
28
|
+
Requires-Dist: httpx>=0.24; extra == 'tests'
|
|
29
|
+
Requires-Dist: pytest; extra == 'tests'
|
|
30
|
+
Requires-Dist: pytest-asyncio; extra == 'tests'
|
|
31
|
+
Requires-Dist: retry; extra == 'tests'
|
|
32
|
+
Requires-Dist: selenium; extra == 'tests'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# python-anticaptcha
|
|
36
|
+
|
|
37
|
+
[](https://github.com/ad-m/python-anticaptcha/actions?workflow=Python+package)
|
|
38
|
+
[](https://pypi.org/project/python-anticaptcha/)
|
|
39
|
+
[](https://gitter.im/python-anticaptcha/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
|
|
40
|
+
[](https://github.com/ad-m/python-anticaptcha/blob/master/pyproject.toml)
|
|
41
|
+
|
|
42
|
+
Client library for solving captchas with [Anticaptcha.com support](http://getcaptchasolution.com/i1hvnzdymd).
|
|
43
|
+
The library requires Python >= 3.9.
|
|
44
|
+
|
|
45
|
+
The library is cyclically and automatically tested for proper operation. We are constantly making the best efforts for its effective operation.
|
|
46
|
+
|
|
47
|
+
In case of any problems with integration - [read the documentation](http://python-anticaptcha.readthedocs.io/en/latest/), [create an issue](https://github.com/ad-m/python-anticaptcha/issues/new), use [Gitter](https://gitter.im/python-anticaptcha/Lobby) or contact privately.
|
|
48
|
+
|
|
49
|
+
## Getting Started
|
|
50
|
+
|
|
51
|
+
Install as standard Python package using:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pip install python-anticaptcha
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For async support (FastAPI, aiohttp, Starlette, etc.):
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
pip install python-anticaptcha[async]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
To use this library you need [Anticaptcha.com](http://getcaptchasolution.com/p9bwplkicx) API key.
|
|
66
|
+
|
|
67
|
+
You can pass the key explicitly or set the `ANTICAPTCHA_API_KEY` environment variable:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Explicit key
|
|
71
|
+
client = AnticaptchaClient("my-api-key")
|
|
72
|
+
|
|
73
|
+
# Or set ANTICAPTCHA_API_KEY environment variable
|
|
74
|
+
client = AnticaptchaClient()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The client can be used as a context manager to ensure the underlying session is closed:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
with AnticaptchaClient(api_key) as client:
|
|
81
|
+
job = client.create_task(task)
|
|
82
|
+
job.join()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Async Usage
|
|
86
|
+
|
|
87
|
+
For async frameworks, use `AsyncAnticaptchaClient` — the API mirrors the sync
|
|
88
|
+
client but all methods are awaitable:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from python_anticaptcha import AsyncAnticaptchaClient, NoCaptchaTaskProxylessTask
|
|
92
|
+
|
|
93
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
94
|
+
site_key = '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-'
|
|
95
|
+
url = 'https://www.google.com/recaptcha/api2/demo'
|
|
96
|
+
|
|
97
|
+
async with AsyncAnticaptchaClient(api_key) as client:
|
|
98
|
+
task = NoCaptchaTaskProxylessTask(url, site_key)
|
|
99
|
+
job = await client.create_task(task)
|
|
100
|
+
await job.join()
|
|
101
|
+
print(job.get_solution_response())
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The full integration example is available in file `examples/async_recaptcha_request.py`.
|
|
105
|
+
|
|
106
|
+
## Sync Usage
|
|
107
|
+
|
|
108
|
+
### Solve recaptcha
|
|
109
|
+
|
|
110
|
+
Example snippet for Recaptcha:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from python_anticaptcha import AnticaptchaClient, NoCaptchaTaskProxylessTask
|
|
114
|
+
|
|
115
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
116
|
+
site_key = '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-' # grab from site
|
|
117
|
+
url = 'https://www.google.com/recaptcha/api2/demo'
|
|
118
|
+
|
|
119
|
+
client = AnticaptchaClient(api_key)
|
|
120
|
+
task = NoCaptchaTaskProxylessTask(url, site_key)
|
|
121
|
+
job = client.create_task(task)
|
|
122
|
+
job.join()
|
|
123
|
+
print(job.get_solution_response())
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The full integration example is available in file `examples/sync_recaptcha_request.py`.
|
|
127
|
+
|
|
128
|
+
If you process the same page many times, to increase reliability you can specify
|
|
129
|
+
whether the captcha is visible or not. This parameter is not required, as the
|
|
130
|
+
system detects invisible sitekeys automatically. To provide that, pass
|
|
131
|
+
`is_invisible` parameter to `NoCaptchaTaskProxylessTask` or `NoCaptchaTask` eg.:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from python_anticaptcha import AnticaptchaClient, NoCaptchaTaskProxylessTask
|
|
135
|
+
|
|
136
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
137
|
+
site_key = '6Lc-0DYUAAAAAOPM3RGobCfKjIE5STmzvZfHbbNx' # grab from site
|
|
138
|
+
url = 'https://losangeles.craigslist.org/lac/kid/d/housekeeper-sitting-pet-care/6720136191.html'
|
|
139
|
+
|
|
140
|
+
client = AnticaptchaClient(api_key)
|
|
141
|
+
task = NoCaptchaTaskProxylessTask(url, site_key, is_invisible=True)
|
|
142
|
+
job = client.create_task(task)
|
|
143
|
+
job.join()
|
|
144
|
+
print(job.get_solution_response())
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Solve text captcha
|
|
148
|
+
|
|
149
|
+
Example snippet for text captcha:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from python_anticaptcha import AnticaptchaClient, ImageToTextTask
|
|
153
|
+
|
|
154
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
155
|
+
client = AnticaptchaClient(api_key)
|
|
156
|
+
|
|
157
|
+
# From a file path:
|
|
158
|
+
task = ImageToTextTask('examples/captcha_ms.jpeg')
|
|
159
|
+
|
|
160
|
+
# Or from raw bytes:
|
|
161
|
+
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb').read())
|
|
162
|
+
|
|
163
|
+
# Or from a file object:
|
|
164
|
+
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb'))
|
|
165
|
+
|
|
166
|
+
job = client.create_task(task)
|
|
167
|
+
job.join()
|
|
168
|
+
print(job.get_captcha_text())
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Solve funcaptcha
|
|
172
|
+
|
|
173
|
+
Example snippet for funcaptcha:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from python_anticaptcha import AnticaptchaClient, FunCaptchaTask, Proxy
|
|
177
|
+
UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 ' \
|
|
178
|
+
'(KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
|
|
179
|
+
|
|
180
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
181
|
+
site_key = 'DE0B0BB7-1EE4-4D70-1853-31B835D4506B' # grab from site
|
|
182
|
+
url = 'https://www.google.com/recaptcha/api2/demo'
|
|
183
|
+
proxy = Proxy.parse_url("socks5://login:password@123.123.123.123:1080")
|
|
184
|
+
|
|
185
|
+
client = AnticaptchaClient(api_key)
|
|
186
|
+
task = FunCaptchaTask(url, site_key, user_agent=UA, **proxy.to_kwargs())
|
|
187
|
+
job = client.create_task(task)
|
|
188
|
+
job.join()
|
|
189
|
+
print(job.get_token_response())
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Monitor solve progress
|
|
193
|
+
|
|
194
|
+
You can pass an `on_check` callback to `job.join()` to monitor progress:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
def progress(elapsed, status):
|
|
198
|
+
print(f"Elapsed: {elapsed}s, status: {status}")
|
|
199
|
+
|
|
200
|
+
job = client.create_task(task)
|
|
201
|
+
job.join(on_check=progress)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Report incorrect image
|
|
205
|
+
|
|
206
|
+
Example snippet for reporting an incorrect image task:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from python_anticaptcha import AnticaptchaClient, ImageToTextTask
|
|
210
|
+
|
|
211
|
+
api_key = '174faff8fbc769e94a5862391ecfd010'
|
|
212
|
+
captcha_fp = open('examples/captcha_ms.jpeg', 'rb')
|
|
213
|
+
client = AnticaptchaClient(api_key)
|
|
214
|
+
task = ImageToTextTask(captcha_fp)
|
|
215
|
+
job = client.create_task(task)
|
|
216
|
+
job.join()
|
|
217
|
+
print(job.get_captcha_text())
|
|
218
|
+
job.report_incorrect_image()
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Setup proxy
|
|
222
|
+
|
|
223
|
+
The library is not responsible for managing the proxy server. However, we point to
|
|
224
|
+
the possibility of simply launching such a server by:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
pip install mitmproxy
|
|
228
|
+
mitmweb -p 9190 -b 0.0.0.0 --ignore '.' --socks
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Then in your application use something like:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
proxy = Proxy.parse_url("socks5://123.123.123.123:9190")
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
We recommend entering IP-based access control for incoming addresses to proxy. IP address required by
|
|
238
|
+
[Anticaptcha.com](http://getcaptchasolution.com/p9bwplkicx) is:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
69.65.41.21
|
|
242
|
+
209.212.146.168
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Error handling
|
|
246
|
+
|
|
247
|
+
In the event of an application error, the `AnticaptchaException` exception is thrown. To handle the exception, do the following:
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from python_anticaptcha import AnticaptchaException, ImageToTextTask
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
# any actions
|
|
254
|
+
except AnticaptchaException as e:
|
|
255
|
+
if e.error_code == 'ERROR_ZERO_BALANCE':
|
|
256
|
+
notify_about_no_funds(e.error_id, e.error_code, e.error_description)
|
|
257
|
+
else:
|
|
258
|
+
raise
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
> **Note:** The legacy misspelled `AnticatpchaException` alias is still available for backward compatibility.
|
|
262
|
+
|
|
263
|
+
## Versioning
|
|
264
|
+
|
|
265
|
+
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the
|
|
266
|
+
[tags on this repository](https://github.com/ad-m/python-anticaptcha/tags).
|
|
267
|
+
|
|
268
|
+
## Authors
|
|
269
|
+
|
|
270
|
+
- **Adam Dobrawy** - *Initial work* - [ad-m](https://github.com/ad-m)
|
|
271
|
+
|
|
272
|
+
See also the list of [contributors](https://github.com/ad-m/python-anticaptcha/contributors) who participated in this project.
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md)
|
|
277
|
+
file for details
|