diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ca9f11c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +# .editorconfig +root = true + +[*] +end_of_line = lf +insert_final_newline = true diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2f68975..ea1e436 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,13 +10,6 @@ assignees: alperensert **Describe the bug** A clear and concise description of what the bug is. -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - **Expected behavior** A clear and concise description of what you expected to happen. @@ -24,11 +17,13 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Simplified error traceback (if you have)** + - Directory: [e.g main] - File: [e.g recaptcha_v2.py] - Line(s): [e.g 30, 66, 82] diff --git a/.github/ISSUE_TEMPLATE/help-wanted.md b/.github/ISSUE_TEMPLATE/help-wanted.md index c49a6d6..a39c793 100644 --- a/.github/ISSUE_TEMPLATE/help-wanted.md +++ b/.github/ISSUE_TEMPLATE/help-wanted.md @@ -8,13 +8,15 @@ assignees: '' --- **Your purpose** -Are you trying to pass a web site protection or can't find the required keys? Can't submit the captcha? Or something else.. Please explain it in here. +Are you trying to pass website protection or can't find the required keys? Can't submit the captcha? Or something else. +Please explain it in here. **Highly required informations** -- Web site url (where placed the captcha) + +- Website url (where placed the captcha) **Things you've tried** The followed way to solve your problem. Explain it briefly, like I changed ... to ... but it doesn't worked -**Do not forget** -90% of help requests was about submitting captcha in web sites. In this cases, please take a look at to **examples** +**Remember** +90% of help requests were about submitting captcha in websites. In this case, please take a look at to **docs**. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ef6f3b6..1532fe2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,6 @@ version: 2 updates: - package-ecosystem: "pip" - directory: "/capmonster_python" - schedule: - interval: "daily" - - package-ecosystem: "npm" - directory: "/docs" + directory: "/src/capmonster_python" schedule: interval: "weekly" - ignore: - - dependency-name: "*" \ No newline at end of file diff --git a/.github/workflows/ghpages.yml b/.github/workflows/ghpages.yml index 3b52de9..6f43b83 100644 --- a/.github/workflows/ghpages.yml +++ b/.github/workflows/ghpages.yml @@ -1,14 +1,14 @@ -name: Deploy Gatsby Documentation to Pages +name: Deploy MkDocs to GitHub Pages on: push: - branches: ["master"] + branches: [ "master" ] paths: - docs/** workflow_dispatch: permissions: - contents: read + contents: write pages: write id-token: write @@ -22,67 +22,22 @@ defaults: working-directory: docs jobs: - build: + deploy: runs-on: ubuntu-latest + steps: - - name: Checkout + - name: Checkout repository uses: actions/checkout@v3 - - name: Detect package manager - id: detect-package-manager - run: | - if [ -f "yarn.lock" ]; then - echo "manager=yarn" >> $GITHUB_OUTPUT - echo "command=install" >> $GITHUB_OUTPUT - echo "file=**/yarn.lock" >> $GITHUB_OUTPUT - exit 0 - elif [ -f "package.json" ]; then - echo "manager=npm" >> $GITHUB_OUTPUT - echo "command=ci" >> $GITHUB_OUTPUT - echo "file=**/package.json" >> $GITHUB_OUTPUT - exit 0 - else - echo "Unable to determine packager manager" - exit 1 - fi - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: "18" - cache: ${{ steps.detect-package-manager.outputs.manager }} - cache-dependency-path: ${{ steps.detect-package-manager.outputs.file }} - - - name: Setup Pages - id: pages - uses: actions/configure-pages@v2 - with: - static_site_generator: gatsby - - name: Restore cache - uses: actions/cache@v3 + + - name: Set up Python + uses: actions/setup-python@v4 with: - path: | - public - .cache - key: ${{ runner.os }}-gatsby-build-${{ hashFiles('public') }} - restore-keys: | - ${{ runner.os }}-gatsby-build- + python-version: '3.10' + - name: Install dependencies - run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} - - name: Build with Gatsby - env: - PREFIX_PATHS: 'true' - run: ${{ steps.detect-package-manager.outputs.manager }} run build - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - path: ./docs/public + run: | + pip install mkdocs mkdocs-material mkdocstrings[python] - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v1 \ No newline at end of file + - name: Build and deploy + run: | + mkdocs gh-deploy --force diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3f65d5b..7f6b61d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,38 +2,37 @@ name: Publish Python Package 🐍 on: release: - types: [published] + types: [ published ] jobs: deploy: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: "3.9" - - - name: Install setup dependencies - run: make setup_dependencies - - - name: Install dependencies - run: make build - - - name: Build package - run: python -m build - - - name: Publish package to TestPYPI - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.TEST_PYPI_TOKEN }} - repository_url: https://test.pypi.org/legacy/ - - - name: Publish package to PYPI - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install setup dependencies + run: make setup_dependencies + + - name: Install dependencies + run: make build + + - name: Build package + run: python -m build + + - name: Publish package to TestPYPI + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.TEST_PYPI_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + + - name: Publish package to PYPI + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..6ab9ed1 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,37 @@ +name: Run Pytest Tests + +on: + push: + branches: [ "master" ] + paths: + - "tests/**" + - ".github/workflows/test.yml" + - "**.py" + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + env: + API_KEY: ${{ secrets.API_KEY }} + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install pytest + + - name: Run tests + run: | + pytest tests/ diff --git a/.gitignore b/.gitignore index 2fe3532..f8bbc8d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ **/.cache **/node_modules **/.DS_Store -**/.venv \ No newline at end of file +**/.venv +**/site +**/dist +**/*.egg-info diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md deleted file mode 100644 index 942d167..0000000 --- a/CODE-OF-CONDUCT.md +++ /dev/null @@ -1,51 +0,0 @@ -# Contributor Code of Conduct - -Our [company values](https://auth0.com/careers/culture) guide us in our day-to-day interactions and decision-making. Our open source projects are no exception. Trust, respect, collaboration and transparency are core values we believe should live and breathe within our projects. Our community welcomes participants from around the world with different experiences, unique perspectives, and great ideas to share. - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Attempting collaboration before conflict -- Focusing on what is best for the community -- Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -- Violence, threats of violence, or inciting others to commit self-harm -- The use of sexualized language or imagery and unwelcome sexual attention or advances -- Trolling, intentionally spreading misinformation, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic address, without explicit permission -- Abuse of the reporting process to intentionally harass or exclude others -- Advocating for, or encouraging, any of the above behavior -- Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting us anonymously through [this form](https://goo.gl/forms/chVYUnA4bP70WGsL2). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. - -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. - -If you are unsure whether an incident is a violation, or whether the space where the incident took place is covered by our Code of Conduct, **we encourage you to still report it**. We would prefer to have a few extra reports where we decide to take no action, than to leave an incident go unnoticed and unresolved that may result in an individual or group to feel like they can no longer participate in the community. Reports deemed as not a violation will also allow us to improve our Code of Conduct and processes surrounding it. If you witness a dangerous situation or someone in distress, we encourage you to report even if you are only an observer. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/Makefile b/Makefile index 4bcb782..00899ce 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,5 @@ install_pkg: python -m pip install --upgrade pip wheel pip install . -test: - python -m unittest -v tests/test_tasks.py - setup_dependencies: pip install setuptools_scm wheel diff --git a/README.md b/README.md index c43fe25..45195f8 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,128 @@ -Capmonster.cloud for Python -= -![PyPI - Wheel](https://img.shields.io/pypi/wheel/capmonster-python?style=plastic) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/capmonster_python?style=flat) ![GitHub last commit](https://img.shields.io/github/last-commit/alperensert/capmonster_python?style=flat) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/alperensert/capmonster_python?style=flat) ![PyPI - Downloads](https://img.shields.io/pypi/dm/capmonster_python?style=flat) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/alperensert/capmonster_python?style=flat) ![GitHub Repo stars](https://img.shields.io/github/stars/alperensert/capmonster_python?style=social) +# πŸ€– Capmonster Python -[Capmonster.cloud](https://capmonster.cloud) package for Python3 +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/capmonster-python?style=for-the-badge) +![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/alperensert/capmonster_python?style=for-the-badge) +![GitHub last commit](https://img.shields.io/github/last-commit/alperensert/capmonster_python?style=for-the-badge) +![GitHub Release](https://img.shields.io/github/v/release/alperensert/capmonster_python?style=for-the-badge) +![GitHub Repo stars](https://img.shields.io/github/stars/alperensert/capmonster_python?style=for-the-badge&color=rgb(255%2C%20255%2C%20143)&cacheSeconds=3600) -If you have any problem with usage, [read the documentation](https://alperensert.github.io/capmonster_python) -or [create an issue](https://github.com/alperensert/capmonster_python/issues/new) +A modern, strongly typed, async-friendly Python SDK for solving CAPTCHA challenges +using [Capmonster.Cloud](https://capmonster.cloud/). -*At least 2x cheaper, up to 30x faster than manual recognition services.* +Supports reCAPTCHA v2 & v3, Cloudflare Turnstile, GeeTest (v3 & v4) and [much more](#-supported-captcha-types). -### Installation +--- -``` +## ✨ Features + +- βœ… Fully typed Pydantic v2 models +- πŸ” Both sync and async API support +- πŸ” Proxy and User-Agent configuration +- πŸ“¦ Supports the most common CAPTCHA types +- πŸ“š Intuitive API with powerful task building + +--- + +## πŸ”§ Installation + +```bash pip install capmonster_python ``` -### Supported captcha types - -- Image to text -- Recaptcha v2 -- Recaptcha v2 Enterprise -- Recaptcha v3 -- Fun Captcha -- HCaptcha -- GeeTest -- Turnstile Task -- Data Dome +> [!IMPORTANT] +> You're viewing the documentation for **Capmonster Python v4**, which includes breaking changes. If you prefer the +> old syntax used in versions prior to 4.x, you can continue using it by installing the legacy version: +> ```pip install capmonster_python==3.2``` -Usage examples -- +## πŸš€ Quick Start -#### ImageToText +### Async Example ```python -from capmonster_python import ImageToTextTask +import asyncio +from capmonster_python import CapmonsterClient, RecaptchaV3Task -capmonster = ImageToTextTask("API_KEY") -task_id = capmonster.create_task(image_path="img.png") -result = capmonster.join_task_result(task_id) -print(result.get("text")) -``` -#### Recaptcha v2 +async def main(): + client = CapmonsterClient(api_key="YOUR_API_KEY") -```python -from capmonster_python import RecaptchaV2Task + task = RecaptchaV3Task( + websiteURL="https://example.com", + websiteKey="SITE_KEY_HERE", + minScore=0.5, + pageAction="verify" + ) -capmonster = RecaptchaV2Task("API_KEY") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) -``` + task_id = await client.create_task_async(task) + result = await client.join_task_result_async(task_id) + print(result) -#### Recaptcha v2 enterprise -```python -from capmonster_python import RecaptchaV2EnterpriseTask +asyncio.run(main()) -capmonster = RecaptchaV2EnterpriseTask("API_KEY") -task_id = capmonster.create_task("website_url", "website_key", {"s": "payload value"}, "api_domain") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) ``` -#### GeeTest +### Sync Example ```python -from capmonster_python import GeeTestTask - -capmonster = GeeTestTask("API_KEY") -task_id = capmonster.create_task("website_url", "gt", "challenge") -result = capmonster.join_task_result(task_id) -print(result.get("challenge")) -print(result.get("seccode")) -print(result.get("validate")) -``` +from capmonster_python import CapmonsterClient, RecaptchaV2Task -#### Report incorrect captchas +client = CapmonsterClient(api_key="") -```python -from capmonster_python import RecaptchaV2Task +task = RecaptchaV2Task( + websiteURL="https://example.com", + websiteKey="SITE_KEY_HERE" +) -capmonster = RecaptchaV2Task("API_KEY") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -report_result = capmonster.report_incorrect_captcha("token", task_id) -print(report_result) +task_id = client.create_task(task) +result = client.join_task_result(task_id) +print(result) ``` -For other examples and api documentation please visit [wiki](https://alperensert.github.io/capmonster_python) \ No newline at end of file +--- + +## 🧠 Supported CAPTCHA Types + +Capmonster Python v4 supports a wide range of CAPTCHA formats β€” from mainstream challenges like reCAPTCHA and Turnstile +to enterprise-grade shields like Imperva and DataDome. Each task supports full Pydantic validation βœ… and both sync and +async clients πŸ”„ unless noted. + +| πŸ”– Category | CAPTCHA Type | Class Name | Proxy Required | Notes | +|---------------------------|--------------------------------|-------------------------------|----------------|----------------------------------------| +| 🧩 reCAPTCHA | reCAPTCHA v2 | `RecaptchaV2Task` | Optional | Visible / Invisible supported βœ… πŸ”„ | +| | reCAPTCHA v2 Enterprise | `RecaptchaV2EnterpriseTask` | Optional | `enterprisePayload` & `apiDomain` βœ… πŸ”„ | +| | reCAPTCHA v3 | `RecaptchaV3Task` | ❌ No | Score-based, proxyless βœ… πŸ”„ | +| πŸ›‘οΈ Cloudflare | Turnstile (token) | `TurnstileTask` | ❌ No | Lightweight, async-ready βœ… πŸ”„ | +| | Turnstile (cf_clearance) | `TurnstileCloudFlareTask` | βœ… Yes | Full HTML + proxy required βœ… πŸ”„ | +| πŸ“Έ Image-based | Image-to-Text OCR | `ImageToTextTask` | ❌ No | Base64 image + module control βœ… πŸ”„ | +| | Complex Image (Recaptcha-like) | `ComplexImageRecaptchaTask` | ❌ No | Grid-based, metadata aware βœ… πŸ”„ | +| | Complex Image Recognition (AI) | `ComplexImageRecognitionTask` | ❌ No | Supports tasks like Shein, OOCL βœ… πŸ”„ | +| 🧠 Human Behavior | GeeTest v3 | `GeeTestV3Task` | Optional | Challenge + `gt` key + freshness βœ… πŸ”„ | +| | GeeTest v4 | `GeeTestV4Task` | Optional | `initParameters` supported βœ… πŸ”„ | +| πŸ›‘οΈ Enterprise Protection | DataDome | `DataDomeTask` | βœ… Recommended | Cookie & page context needed βœ… πŸ”„ | +| | Imperva | `ImpervaTask` | βœ… Recommended | Incapsula + Reese84 logic βœ… πŸ”„ | +| 🏦 Platform-Specific | Binance Login | `BinanceTask` | βœ… Yes | `validateId` for login flow βœ… πŸ”„ | +| | Temu | `TemuTask` | ❌ No | Cookie-injected behavioral solver βœ… πŸ”„ | +| | TenDI | `TenDITask` | βœ… Yes | Custom captchaAppId field βœ… πŸ”„ | +| πŸ§ͺ Miscellaneous | Prosopo | `ProsopoTask` | Optional | Used in zk or crypto UIs βœ… πŸ”„ | +| | Basilisk | `BasiliskTask` | ❌ No | Minimalist site-key puzzle βœ… πŸ”„ | + +## 🧩 Advanced Usage + +- Callback URLs are supported during task creation. +- Includes auto-retry loop for polling results (up to 120s) + +## πŸ’¬ Community & Support + +Need help or have a question? + +- πŸ“§ Contact: business@alperen.io +- πŸ› Found a bug? [Open an issue](https://github.com/alperensert/capmonster_python/issues) + +> [!NOTE] +> Community support is intended only for questions and issues related to this project. Custom usage scenarios, +> integrations, or application-specific logic are outside the scope of support. + +## πŸ“„ License + +This project is licensed under the [MIT License](/LICENSE). diff --git a/capmonster_python/__init__.py b/capmonster_python/__init__.py deleted file mode 100644 index 74caf5b..0000000 --- a/capmonster_python/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from .recaptcha_v2 import RecaptchaV2Task -from .recaptcha_v2_enterprise import RecaptchaV2EnterpriseTask -from .fun_captcha import FuncaptchaTask -from .recaptcha_v3 import RecaptchaV3Task -from .hcaptcha import HCaptchaTask -from .image_to_text import ImageToTextTask -from .geetest import GeeTestTask -from .utils import CapmonsterException -from .compleximage import ComplexImageTask -from .datadome import DataDomeTask -from .turnstile import TurnstileTask -from .tendi import TenDITask -from .aws_waf import AmazonWafTask diff --git a/capmonster_python/aws_waf.py b/capmonster_python/aws_waf.py deleted file mode 100644 index 144a9bf..0000000 --- a/capmonster_python/aws_waf.py +++ /dev/null @@ -1,22 +0,0 @@ -from .capmonster import Capmonster - -class AmazonWafTask(Capmonster): - def __init__(self, client_key): - super(AmazonWafTask, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str, challenge_script: str, captcha_script: str, - context: str, iv: str, cookieSolution: bool = False): - data = { - "clientKey": self._client_key, - "task": { - "type": "AmazonTaskProxyless", - "websiteURL": website_url, - "websiteKey": website_key, - "challengeScript": challenge_script, - "captchaScript": captcha_script, - "context": context, - "iv": iv, - "cookieSolution": cookieSolution - } - } - return self._make_request("createTask", data).get("taskId") \ No newline at end of file diff --git a/capmonster_python/capmonster.py b/capmonster_python/capmonster.py deleted file mode 100644 index 6436fb5..0000000 --- a/capmonster_python/capmonster.py +++ /dev/null @@ -1,253 +0,0 @@ -import requests -import asyncio -from time import sleep -from .utils import * - - -class Capmonster: - """A class that interacts with the Capmonster API.""" - __SOFT_ID = 30 - _HOST_URL = "https://api.capmonster.cloud" - _CREATE_TASK_URL = "/createTask" - _TASK_RESULT_URL = "/getTaskResult" - _BALANCE_URL = "/getBalance" - _INCORRECT_IMAGE_CAPTCHA_URL = "/reportIncorrectImageCaptcha" - _INCORRECT_TOKEN_CAPTCHA_URL = "/reportIncorrectTokenCaptcha" - - def __init__(self, client_key): - self._client_key = client_key - - def get_balance(self) -> float: - """ - Retrieves the balance of the client. - - :return: The balance of the client as a float. - """ - data = {"clientKey": self._client_key} - return self._make_request("getBalance", data).get("balance") - - def get_task_result(self, task_id: int): - """ - :param task_id: The ID of the task for which the result is requested. - :return: The result of the task if it is ready, otherwise False. - """ - data = { - "clientKey": self._client_key, - "taskId": task_id - } - result = self._make_request("getTaskResult", data) - is_ready = self._is_ready(result) - if is_ready: - return result.get("solution") - else: - return False - - def join_task_result(self, task_id: int, maximum_time: int = 120): - for i in range(0, maximum_time + 1, 2): - result = self.get_task_result(task_id) - if result is not False and result is not None: - return result - elif result is False: - i += 1 - sleep(2) - raise CapmonsterException( - 61, "ERROR_MAXIMUM_TIME_EXCEED", "Maximum time is exceed.") - - async def join_task_result_async(self, task_id: int, maximum_time: int = 120): - for i in range(0, maximum_time + 1, 2): - result = self.get_task_result(task_id) - if result is not False and result is not None: - return result - elif result is False: - i += 1 - await asyncio.sleep(2) - raise CapmonsterException( - 61, "ERROR_MAXIMUM_TIME_EXCEED", "Maximum time is exceed.") - - def report_incorrect_captcha(self, captcha_type: str, task_id: int) -> bool: - """ - Reports an incorrect captcha. - - :param captcha_type: The type of captcha ("image" or "token"). - :param task_id: The ID of the task. - :return: True if the captcha is successfully reported, False otherwise. - :raises CapmonsterException: If the captcha type is invalid. - """ - valid_captcha_types = ["image", "token"] - - if captcha_type not in valid_captcha_types: - raise CapmonsterException( - 1, "ERROR_INCORRECT_CAPTCHA_TYPE", "Valid captcha_type parameters are only 'image' or 'token'.") - try: - self._report_incorrect_captcha( - captcha_type=captcha_type, task_id=task_id) - return True - except: - return False - - @check_response() - def _report_incorrect_captcha(self, captcha_type: str, task_id: int): - data = { - "clientKey": self._client_key, - "taskId": task_id - } - if captcha_type == "image": - response = self._make_request("reportIncorrectImageCaptcha", data) - else: - response = self._make_request("reportIncorrectTokenCaptcha", data) - return response - - @staticmethod - def _is_ready(response: dict): - status = response.get("status") - if status == "processing": - return False - elif status == "ready": - return True - - @check_response() - def _make_request(self, method: str, data: dict): - _method = None - if method == "getBalance": - _method = self._BALANCE_URL - elif method == "getTaskResult": - _method = self._TASK_RESULT_URL - elif method == "createTask": - _method = self._CREATE_TASK_URL - data["softId"] = self.__SOFT_ID - elif method == "reportIncorrectImageCaptcha": - _method = self._INCORRECT_IMAGE_CAPTCHA_URL - elif method == "reportIncorrectTokenCaptcha": - _method = self._INCORRECT_TOKEN_CAPTCHA_URL - try: - response = requests.post("{}{}".format( - self._HOST_URL, _method), json=data).json() - except Exception as err: - raise CapmonsterException(-1, type(err).__name__, str(err)) - return response - - @staticmethod - def _add_cookies(cookies, data): - if cookies is None: - return data - str_cookies = "" - if type(cookies) is dict: - for key, value in cookies.items(): - if value == list(cookies.items())[-1][1]: - str_cookies += "{}={}".format(key, value) - else: - str_cookies += "{}={};".format(key, value) - elif type(cookies) is list: - for i in cookies: - if not len(cookies) % 2 == 0: - raise AttributeError( - "List cookies length must be even numbers") - if cookies.index(i) % 2 == 0: - str_cookies += "{}=".format(i) - elif cookies[cookies.index(i)] == cookies[-1]: - str_cookies += "{}".format(i) - elif cookies.index(i) % 2 == 1: - str_cookies += "{};".format(i) - elif type(cookies) is str: - data["task"]["cookies"] = cookies - return data - data["task"]["cookies"] = str_cookies - return data - - -class Proxy(Capmonster): - def __init__(self, client_key): - super().__init__(client_key) - self._proxy_type = None - self._proxy_address = None - self._proxy_port = None - self._proxy_login = None - self._proxy_password = None - - def set_proxy(self, proxy_type: str, proxy_address: str, proxy_port: int, - proxy_login: str = None, proxy_password: str = None): - """ - Sets the proxy settings for the client. - - :param proxy_type: The type of the proxy. (e.g. "HTTP", "SOCKS5") - :param proxy_address: The address of the proxy server. - :param proxy_port: The port number of the proxy server. - :param proxy_login: (optional) The login username for proxy authentication. - :param proxy_password: (optional) The login password for proxy authentication. - :return: None - """ - self._proxy_type = proxy_type - self._proxy_address = proxy_address - self._proxy_port = proxy_port - self._proxy_login = proxy_login - self._proxy_password = proxy_password - - def disable_proxy(self): - """ - Disables the proxy settings. - - :return: None - """ - self._proxy_type = None - self._proxy_address = None - self._proxy_port = None - self._proxy_login = None - self._proxy_password = None - - def _is_proxy_task(self, data: dict): - """ - Determine for is this a proxy task or not? - e.g. if you are not set the values with set_proxy method, it is a proxyless method, or if you are set up it is a - proxy task. - """ - if self._proxy_type and self._proxy_address and self._proxy_port: - data["task"]["proxyType"] = self._proxy_type - data["task"]["proxyAddress"] = self._proxy_address - data["task"]["proxyPort"] = self._proxy_port - if self._proxy_login and self._proxy_password: - data["task"]["proxyLogin"] = self._proxy_login - data["task"]["proxyPassword"] = self._proxy_password - return data, True - data["task"]["type"] += "Proxyless" - return data, False - - -class UserAgent(Capmonster): - def __init__(self, client_key): - super().__init__(client_key) - self._user_agent = None - self._fallback = False - - def set_user_agent(self, user_agent: str): - """ - Set the user agent for the instance. - - :param user_agent: The user agent string to set. - :return: None - """ - self._user_agent = user_agent - - def reset_user_agent(self): - """ - Reset the user agent to None. - - :return: - """ - self._user_agent = None - - def _add_user_agent(self, data): - data["task"]["fallbackToActualUA"] = self._fallback - if self._user_agent: - data["task"]["userAgent"] = self._user_agent - return data, True - return data, False - - def set_fallback_to_actual_user_agent(self, fallback: bool): - """ - Set the fallback value for the actual user agent. - - :param fallback: A boolean value indicating whether to enable or disable the fallback. - :type fallback: bool - :return: None - """ - self._fallback = fallback diff --git a/capmonster_python/compleximage.py b/capmonster_python/compleximage.py deleted file mode 100644 index d25b96e..0000000 --- a/capmonster_python/compleximage.py +++ /dev/null @@ -1,51 +0,0 @@ -from .capmonster import UserAgent - - -class ComplexImageTask(UserAgent): - __VALID_CLASSES = ["recaptcha", "hcaptcha"] - - def __init__(self, client_key): - super(ComplexImageTask, self).__init__(client_key) - - def create_task(self, _class: str, grid: str = None, - task_definition: str = None, - image_urls: list = None, - images_base64: list = None, - task: str = None, - websiteUrl: str = None): - if _class not in self.__VALID_CLASSES: - raise ValueError("Currently only recaptcha or hcaptcha is supported as _class value.") - data = { - "clientKey": self._client_key, - "task": { - "type": "ComplexImageTask", - "class": _class, - "metadata": {} - } - } - if image_urls is not None: - data["task"]["imageUrls"] = image_urls - elif images_base64 is not None: - data["task"]["imagesBase64"] = images_base64 - else: - raise ValueError("image_urls or images_base64 must be sent") - if _class == "recaptcha": - if grid is None: - raise ValueError("Grid parameter must sent with recaptcha") - else: - data["task"]["metadata"]["Grid"] = grid - if task is not None: - data["task"]["metadata"]["Task"] = task - elif task_definition is not None: - data["task"]["metadata"]["TaskDefinition"] = task_definition - else: - raise ValueError("task_definition or task parameter must be sent") - elif _class == "hcaptcha": - if task is not None: - data["task"]["metadata"]["Task"] = task - else: - raise ValueError("task parameter must be sent with hcaptcha") - if websiteUrl is not None: - data["task"]["websiteUrl"] = websiteUrl - data, is_user_agent = self._add_user_agent(data) - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/datadome.py b/capmonster_python/datadome.py deleted file mode 100644 index 6f24a12..0000000 --- a/capmonster_python/datadome.py +++ /dev/null @@ -1,19 +0,0 @@ -from .capmonster import UserAgent - - -class DataDomeTask(UserAgent): - def __init__(self, client_key): - super(DataDomeTask, self).__init__(client_key) - - def create_task(self, website_url: str, metadata: object): - data = { - "client_key": self._client_key, - "task": { - "type": "CustomTask", - "class": "DataDome", - "websiteURL": website_url, - "metadata": metadata, - } - } - data, is_user_agent = self._add_user_agent(data) - return self._make_request("createTask", data=data).get("taskId") diff --git a/capmonster_python/fun_captcha.py b/capmonster_python/fun_captcha.py deleted file mode 100644 index 9434e23..0000000 --- a/capmonster_python/fun_captcha.py +++ /dev/null @@ -1,30 +0,0 @@ -from .capmonster import Proxy, UserAgent -from typing import Union - - -class FuncaptchaTask(UserAgent, Proxy): - def __init__(self, client_key): - super(FuncaptchaTask, self).__init__(client_key) - - def create_task(self, website_url: str, website_public_key: str, api_js_subdomain: str = None, - data_blob: str = None, cookies: Union[dict, list, str] = None, no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "FunCaptchaTask", - "websiteURL": website_url, - "websitePublicKey": website_public_key - } - } - if data_blob is not None: - data["task"]["data"] = data_blob - data, is_proxy = self._is_proxy_task(data) - if is_proxy: - data, is_user_agent = self._add_user_agent(data) - if cookies is not None: - data = self._add_cookies(cookies, data) - if api_js_subdomain is not None: - data["task"]["funcaptchaApiJSSubdomain"] = api_js_subdomain - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/geetest.py b/capmonster_python/geetest.py deleted file mode 100644 index 179fafe..0000000 --- a/capmonster_python/geetest.py +++ /dev/null @@ -1,26 +0,0 @@ -from .capmonster import Proxy, UserAgent - - -class GeeTestTask(UserAgent, Proxy): - def __init__(self, client_key): - super(GeeTestTask, self).__init__(client_key) - - def create_task(self, website_url: str, gt: str, challenge: str, - api_server_subdomain: str = None, get_lib: str = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "GeeTestTask", - "websiteURL": website_url, - "gt": gt, - "challenge": challenge - } - } - data, is_user_agent = self._add_user_agent(data) - data, is_proxy = self._is_proxy_task(data) - if api_server_subdomain: - data["task"]["geetestApiServerSubdomain"] = api_server_subdomain - if get_lib: - data["task"]["geetestGetLib"] = get_lib - return self._make_request("createTask", data).get("taskId") - diff --git a/capmonster_python/hcaptcha.py b/capmonster_python/hcaptcha.py deleted file mode 100644 index 73302cb..0000000 --- a/capmonster_python/hcaptcha.py +++ /dev/null @@ -1,36 +0,0 @@ -from .capmonster import Proxy, UserAgent -from .utils import CapmonsterException -from typing import Union - - -class HCaptchaTask(UserAgent, Proxy): - def __init__(self, client_key): - super(HCaptchaTask, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str, is_invisible: bool = None, custom_data: str = None, - cookies: Union[dict, list, str] = None, no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "HCaptchaTask", - "websiteURL": website_url, - "websiteKey": website_key - } - } - if cookies is not None: - data = self._add_cookies(cookies, data) - if is_invisible is not None: - data["task"]["isInvisible"] = is_invisible - if custom_data is not None: - data, is_user_agent = self._add_user_agent(data) - if is_user_agent is False: - raise CapmonsterException(-1, - "USER_AGENT_ERROR", - "You must provide an user agent if you submit captcha with custom_data") - data["task"]["data"] = custom_data - if custom_data is None: - data, is_user_agent = self._add_user_agent(data) - data, is_proxy = self._is_proxy_task(data) - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/image_to_text.py b/capmonster_python/image_to_text.py deleted file mode 100644 index 9cfd58a..0000000 --- a/capmonster_python/image_to_text.py +++ /dev/null @@ -1,43 +0,0 @@ -from .capmonster import Capmonster, CapmonsterException -from base64 import b64encode - - -class ImageToTextTask(Capmonster): - def __init__(self, client_key): - super().__init__(client_key) - - def create_task(self, image_path: str = None, base64_encoded_image: str = None, module: str = None, - recognizing_threshold: int = None, case: bool = None, numeric: int = None, - math: bool = None): - if base64_encoded_image is None and image_path is None: - raise CapmonsterException(error_id=-1, - error_code="ERROR_NOTHING_GIVEN", - error_description="You have to give image_path or base64_encoded_image") - data = { - "clientKey": self._client_key, - "task": { - "type": "ImageToTextTask" - } - } - if base64_encoded_image is None: - img_body = self._from_path(image_path) - data["task"]["body"] = img_body - else: - data["task"]["body"] = base64_encoded_image - if module is not None: - data["task"]["CapMonsterModule"] = module - if recognizing_threshold is not None and (0 <= recognizing_threshold <= 100): - data["task"]["recognizingThreshold"] = recognizing_threshold - if case is not None: - data["task"]["Case"] = case - if numeric is not None and (0 <= numeric <= 1): - data["task"]["numeric"] = numeric - if math is not None: - data["task"]["math"] = math - return self._make_request("createTask", data).get("taskId") - - @staticmethod - def _from_path(image_path: str): - with open(image_path, "rb") as img: - base64_img = b64encode(img.read()).decode("ascii") - return base64_img diff --git a/capmonster_python/recaptcha_v2.py b/capmonster_python/recaptcha_v2.py deleted file mode 100644 index 5eb18f9..0000000 --- a/capmonster_python/recaptcha_v2.py +++ /dev/null @@ -1,27 +0,0 @@ -from .capmonster import Proxy, UserAgent -from typing import Union - - -class RecaptchaV2Task(UserAgent, Proxy): - def __init__(self, client_key): - super(RecaptchaV2Task, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str, - cookies: Union[dict, list, str] = None, recaptcha_s_value: str = None, - no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "NoCaptchaTask", - "websiteURL": website_url, - "websiteKey": website_key - } - } - data, is_proxy = self._is_proxy_task(data) - data, is_user_agent = self._add_user_agent(data) - data = self._add_cookies(cookies, data) - if recaptcha_s_value is not None: - data["task"]["recaptchaDataSValue"] = recaptcha_s_value - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/recaptcha_v2_enterprise.py b/capmonster_python/recaptcha_v2_enterprise.py deleted file mode 100644 index 941a40e..0000000 --- a/capmonster_python/recaptcha_v2_enterprise.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Union -from .capmonster import Proxy, UserAgent - - -class RecaptchaV2EnterpriseTask(UserAgent, Proxy): - def __init__(self, client_key): - super(RecaptchaV2EnterpriseTask, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str, - enterprise_payload=None, api_domain: str = None, - cookies: Union[dict, list, str] = None, - no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "RecaptchaV2EnterpriseTask", - "websiteURL": website_url, - "websiteKey": website_key - } - } - data, is_proxy = self._is_proxy_task(data) - data, is_user_agent = self._add_user_agent(data) - data = self._add_cookies(cookies, data) - if enterprise_payload is not None: - data["task"]["enterprisePayload"] = enterprise_payload - if api_domain is not None: - data["task"]["apiDomain"] = api_domain - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/recaptcha_v3.py b/capmonster_python/recaptcha_v3.py deleted file mode 100644 index cec0359..0000000 --- a/capmonster_python/recaptcha_v3.py +++ /dev/null @@ -1,24 +0,0 @@ -from .capmonster import Capmonster - - -class RecaptchaV3Task(Capmonster): - def __init__(self, client_key): - super().__init__(client_key) - - def create_task(self, website_url: str, website_key: str, minimum_score: float = 0.3, - page_action: str = None, no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "RecaptchaV3TaskProxyless", - "websiteURL": website_url, - "websiteKey": website_key - } - } - if 0.1 <= minimum_score <= 0.9: - data["task"]["minScore"] = minimum_score - if page_action is not None: - data["task"]["pageAction"] = page_action - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/tendi.py b/capmonster_python/tendi.py deleted file mode 100644 index 66d79bf..0000000 --- a/capmonster_python/tendi.py +++ /dev/null @@ -1,19 +0,0 @@ -from .capmonster import UserAgent - -class TenDITask(UserAgent): - def __init__(self, client_key): - super(TenDITask, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str): - data = { - "clientKey": self._client_key, - "task": { - "type": "CustomTask", - "class": "TenDI", - "websiteURL": website_url, - "websiteKey": website_key - } - } - - data, is_user_agent = self._add_user_agent(data) - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/turnstile.py b/capmonster_python/turnstile.py deleted file mode 100644 index e14e436..0000000 --- a/capmonster_python/turnstile.py +++ /dev/null @@ -1,23 +0,0 @@ -from .capmonster import Proxy, UserAgent -from typing import Union - - -class TurnstileTask(UserAgent, Proxy): - def __init__(self, client_key): - super(TurnstileTask, self).__init__(client_key) - - def create_task(self, website_url: str, website_key: str, - no_cache: bool = None): - data = { - "clientKey": self._client_key, - "task": { - "type": "TurnstileTask", - "websiteURL": website_url, - "websiteKey": website_key - } - } - data, is_user_agent = self._add_user_agent(data) - data, is_proxy = self._is_proxy_task(data) - if no_cache: - data["task"]["nocache"] = no_cache - return self._make_request("createTask", data).get("taskId") diff --git a/capmonster_python/utils.py b/capmonster_python/utils.py deleted file mode 100644 index 21c83d7..0000000 --- a/capmonster_python/utils.py +++ /dev/null @@ -1,35 +0,0 @@ -from functools import wraps - - -class CapmonsterException(Exception): - def __init__(self, error_id, error_code, error_description, *args, **kwargs): - super(CapmonsterException, self).__init__("[{}:{}]{}".format(error_code, error_id, error_description)) - self.error_description = error_description - self.error_id = error_id - self.error_code = error_code - - def __str__(self): - return "[{}] {}".format(self.error_code, self.error_description) - - -def check_response(): - def checker(f): - @wraps(f) - def wrap(*args, **kwargs): - rf = f(*args, **kwargs) - if type(rf) is dict: - if rf.get("errorId") == 0: - return rf - else: - raise CapmonsterException(error_id=rf.get("errorId"), - error_code=rf.get("errorCode"), - error_description=rf.get("errorDescription")) - else: - raise CapmonsterException(error_id=-1, - error_code="CAPMONSTER_API_ERROR", - error_description="Sometimes can be happen if capmonster_python " - "servers there is too much intensity") - - return wrap - - return checker diff --git a/docs/error_codes.md b/docs/error_codes.md new file mode 100644 index 0000000..da06d70 --- /dev/null +++ b/docs/error_codes.md @@ -0,0 +1,174 @@ +# ❗ Error Codes + +This page documents common error codes returned by the CapMonster Cloud API along with their meanings and possible +solutions. + +--- + +## πŸ” Authentication & Authorization + +### `ERROR_KEY_DOES_NOT_EXIST` + +**Invalid API Key** +The authorization key provided is not recognized or is in the wrong format. +β†’ Check your API key from the [CapMonster Dashboard](https://capmonster.cloud/). + +### `ERROR_ZERO_BALANCE` + +**No Funds** +Your account balance is zero. +β†’ Add credits to continue solving captchas. + +### `ERROR_IP_NOT_ALLOWED` + +**IP Not Allowed** +Requests from your current IP address are not allowed. +β†’ Add your IP to the **trusted list** in your account settings. + +### `ERROR_IP_BANNED` + +**IP Banned** +Too many failed requests with incorrect API key from your IP. +β†’ Verify your key, wait a few minutes, and try again. + +### `ERROR_IP_BLOCKED` + +**Your IP is Blocked** +Your IP is permanently blocked due to repeated violations or suspicious activity. +β†’ Contact CapMonster support. + +--- + +## πŸ–ΌοΈ CAPTCHA File Issues + +### `ERROR_TOO_BIG_CAPTCHA_FILESIZE` + +**Captcha Image Too Large** +The image size exceeds 500 KB. +β†’ Compress or resize the image before submitting. + +### `ERROR_ZERO_CAPTCHA_FILESIZE` + +**Captcha Image Too Small** +The image size is less than 100 bytes. +β†’ Ensure the image is valid and properly encoded. + +### `ERROR_CAPTCHA_UNSOLVABLE` + +**Captcha Unsolvable** +The image may be too noisy, corrupted, or unsupported by the service. +β†’ Try another image or adjust your task. + +--- + +## πŸ•“ Timing & Task States + +### `ERROR_NO_SUCH_CAPCHA_ID` / `WRONG_CAPTCHA_ID` + +**Captcha ID Not Found** +No task found for the given ID, or the request was made after it expired. +β†’ Poll results within 5 minutes of task creation. + +### `CAPTCHA_NOT_READY` + +**Captcha Not Ready** +The task is still being processed. +β†’ Retry after 1–2 seconds. + +### `ERROR_RECAPTCHA_TIMEOUT` + +**ReCAPTCHA Timeout** +Task solving took too long, possibly due to slow proxy or server issues. +β†’ Use a faster proxy or adjust timeout settings. + +--- + +## 🌐 Domain & SiteKey Errors + +### `ERROR_DOMAIN_NOT_ALLOWED` + +**Domain Blocked** +CapMonster Cloud does not support solving captchas for the specified domain. +β†’ Use a different domain or provider. + +### `ERROR_RECAPTCHA_INVALID_SITEKEY` + +**Invalid SiteKey** +The specified `websiteKey` is not valid. +β†’ Double-check the `data-sitekey` on the target page. + +### `ERROR_RECAPTCHA_INVALID_DOMAIN` + +**Invalid Domain** +The domain doesn’t match the sitekey's origin. +β†’ Ensure both belong to the same origin. + +### `ERROR_TOKEN_EXPIRED` + +**Token Expired** +The challenge token has expired. +β†’ Create a new task with a fresh token. + +--- + +## πŸ“¦ Task Definition Errors + +### `ERROR_NO_SUCH_METHOD` + +**Incorrect Method** +The specified task type (in `type`) is invalid or unsupported. + +### `ERROR_TASK_NOT_SUPPORTED` + +**Incorrect Task Type** +The task format is not recognized. +β†’ Review the `type` value and match it to the correct schema. + +### `ERROR_TASK_ABSENT` + +**Missing Task Object** +No `task` object was provided, or the JSON is malformed. + +### `ERROR_WRONG_USERAGENT` + +**Invalid User-Agent** +The specified User-Agent string is no longer accepted. +β†’ Update to a current, valid browser UA string. + +--- + +## 🌐 Proxy Errors + +### `ERROR_PROXY_CONNECT_REFUSED` + +**Proxy Connection Failed** +Unable to reach proxy server. +β†’ Test your proxy or replace it. + +### `ERROR_PROXY_BANNED` + +**Proxy Banned** +The proxy IP is blocked by the target captcha provider. +β†’ Rotate your proxy or try a different provider. + +--- + +## ⚠️ Service Load & Rate Limits + +### `ERROR_TOO_MUCH_REQUESTS` + +**Too Many Result Polls** +You polled for the task result too frequently. +β†’ Wait at least 2 seconds between requests. + +### `ERROR_NO_SLOT_AVAILABLE` + +**No Free Servers** +All recognition servers are currently busy. +β†’ Retry after a short delay. + +??? warning + + These error codes are related to Capmonster.cloud and not created by us. + + You can reach the latest version from [here](https://docs.capmonster.cloud/docs/api/api-errors). diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..764dc63 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,624 @@ +# πŸ§ͺ Capmonster Python Examples + +Below are example usages for various task types, shown in both async and sync format using `CapmonsterClient`. + +--- + +## reCAPTCHA v2 + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, RecaptchaV2Task + + async def main(): + client = CapmonsterClient(api_key="") + task = RecaptchaV2Task( + websiteURL="https://example.com", + websiteKey="", + isInvisible=False + ) + task_id = await client.create_task_async(task=task) + result = await client.get_task_result_async(task_id=task_id) + print(result.get("gRecaptchaResponse")) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, RecaptchaV2Task + + client = CapmonsterClient(api_key="") + task_id = client.create_task(task=RecaptchaV2Task( + websiteURL="https://example.com", + websiteKey="", + isInvisible=False + )) + response = client.get_task_result(task_id=task_id) + print(response.get("gRecaptchaResponse")) + ``` + +--- + +## ImageToText + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, ImageToTextTask + + async def main(): + client = CapmonsterClient(api_key="") + task = ImageToTextTask( + body="", + recognizingThreshold=95 + ) + task_id = await client.create_task_async(task=task) + result = await client.get_task_result_async(task_id=task_id) + print(result.get("text")) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, ImageToTextTask + + client = CapmonsterClient(api_key="") + task = ImageToTextTask( + body="", + recognizingThreshold=95 + ) + task_id = client.create_task(task=task) + response = client.get_task_result(task_id=task_id) + print(response.get("text")) + ``` + +--- + +## GeeTest v3 + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, GeeTestV3Task + + async def main(): + client = CapmonsterClient(api_key="") + task = GeeTestV3Task( + websiteURL="https://example.com", + gt="", + challenge="" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, GeeTestV3Task + + client = CapmonsterClient(api_key="") + task_id = client.create_task(GeeTestV3Task( + websiteURL="https://example.com", + gt="", + challenge="" + )) + result = client.get_task_result(task_id) + print(result) + ``` + +--- + +## GeeTest v4 + +Used for solving advanced GeeTest v4 captchas which require both `gt` and `initParameters`. +The challenge is generated dynamically per user and must be fresh. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, GeeTestV4Task + + async def main(): + client = CapmonsterClient(api_key="") + task = GeeTestV4Task( + websiteURL="https://example.com", + gt="", + initParameters={"riskType": "slide"} + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, GeeTestV4Task + + client = CapmonsterClient(api_key="") + task_id = client.create_task(GeeTestV4Task( + websiteURL="https://example.com", + gt="", + initParameters={"riskType": "slide"} + )) + result = client.get_task_result(task_id) + print(result) + ``` + +--- + +## DataDome + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, DataDomeTask, DataDomeMetadata + + async def main(): + client = CapmonsterClient(api_key="") + task = DataDomeTask( + websiteURL="https://example.com", + metadata=DataDomeMetadata( + datadomeCookie="datadome=...", + captchaUrl="https://captcha-url" + ) + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, DataDomeTask, DataDomeMetadata + + client = CapmonsterClient(api_key="") + task_id = client.create_task(DataDomeTask( + websiteURL="https://example.com", + metadata=DataDomeMetadata( + datadomeCookie="datadome=...", + captchaUrl="https://captcha-url" + ) + )) + result = client.get_task_result(task_id) + print(result) + ``` + +--- + +## Complex Image reCAPTCHA + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, ComplexImageRecaptchaTask, ComplexImageRecaptchaMetadata + + async def main(): + client = CapmonsterClient(api_key="") + task = ComplexImageRecaptchaTask( + imageUrls=["https://cdn.example.com/captcha1.png"], + metadata=ComplexImageRecaptchaMetadata(Task="Click on traffic lights", Grid="3x3") + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, ComplexImageRecaptchaTask, ComplexImageRecaptchaMetadata + + client = CapmonsterClient(api_key="") + task = ComplexImageRecaptchaTask( + imageUrls=["https://cdn.example.com/captcha1.png"], + metadata=ComplexImageRecaptchaMetadata(Task="Click on traffic lights", Grid="3x3") + ) + task_id = client.create_task(task=task) + result = client.get_task_result(task_id) + print(result) + ``` + +--- + +## Imperva + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, ImpervaTask, ImpervaTaskMetadata + + async def main(): + client = CapmonsterClient(api_key="") + task = ImpervaTask( + websiteURL="https://example.com", + metadata=ImpervaTaskMetadata( + incapsulaScriptUrl="https://example.com/js.inc", + incapsulaCookie="visid_incap_12345=...", + ) + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, ImpervaTask, ImpervaTaskMetadata + + client = CapmonsterClient(api_key="") + task_id = client.create_task(ImpervaTask( + websiteURL="https://example.com", + metadata=ImpervaTaskMetadata( + incapsulaScriptUrl="https://example.com/js.inc", + incapsulaCookie="visid_incap_12345=...", + ) + )) + result = client.get_task_result(task_id) + print(result) + ``` + +## Basilisk + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, BasiliskTask + + async def main(): + client = CapmonsterClient(api_key="") + task = BasiliskTask( + websiteURL="https://example.com", + websiteKey="site_key_value" + ) + task_id = await client.create_task_async(task=task) + result = await client.get_task_result_async(task_id=task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, BasiliskTask + + client = CapmonsterClient(api_key="") + task_id = client.create_task(BasiliskTask( + websiteURL="https://example.com", + websiteKey="site_key_value" + )) + result = client.get_task_result(task_id=task_id) + print(result) + ``` + +## Binance + +Used specifically for login flows involving Binance CAPTCHA protection. +You must supply a valid `validateId` (such as `securityId`, `validateId`, or similar) retrieved from the page. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, BinanceTask + + async def main(): + client = CapmonsterClient(api_key="") + task = BinanceTask( + websiteURL="https://binance.com", + websiteKey="binance-key", + validateId="securityCheckResponseValidateId_value" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, BinanceTask + + client = CapmonsterClient(api_key="") + task_id = client.create_task(BinanceTask( + websiteURL="https://binance.com", + websiteKey="binance-key", + validateId="securityCheckResponseValidateId_value" + )) + result = client.get_task_result(task_id) + print(result) + ``` + +## Temu + +Used to bypass CAPTCHA challenges on Temu using extracted cookies. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, TemuTask + + + async def main(): + client = CapmonsterClient(api_key="") + task = TemuTask( + websiteURL="https://temu.com", + cookie="session_id=abc123;" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, TemuTask + + client = CapmonsterClient(api_key="") + task_id = client.create_task(TemuTask( + websiteURL="https://temu.com", + cookie="session_id=abc123;cookie_2=value2;" + )) + result = client.get_task_result(task_id) + print(result) + ``` + +## TenDI + +Used to solve TenDI-based captcha challenges with a known `websiteKey` (captchaAppId). + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, TenDITask, ProxyPayload + + async def main(): + client = CapmonsterClient(api_key="") + task = TenDITask( + websiteURL="https://example.com", + websiteKey="189123456", + proxy=ProxyPayload( + proxyType="https", + proxyAddress="192.168.1.1", + proxyPort=8080, + proxyLogin="", + proxyPassword="" + ) + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, TenDITask, ProxyPayload + + client = CapmonsterClient(api_key="") + task = TenDITask( + websiteURL="https://example.com", + websiteKey="189123456", + proxy=ProxyPayload( + proxyType="https", + proxyAddress="192.168.1.1", + proxyPort=8080, + proxyLogin="", + proxyPassword="" + ) + ) + task_id = client.create_task(task=task) + result = client.get_task_result(task_id) + print(result) + ``` + +## TurnstileTask (Token-based) + +For solving Cloudflare Turnstile captchas using token mode. No proxy required. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, TurnstileTask + + async def main(): + client = CapmonsterClient(api_key="") + task = TurnstileTask( + websiteURL="https://example.com", + websiteKey="turnstile-site-key" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, TurnstileTask + + client = CapmonsterClient(api_key="") + task_id = client.create_task(TurnstileTask( + websiteURL="https://example.com", + websiteKey="turnstile-site-key" + )) + result = client.get_task_result(task_id) + print(result) + ``` + +## TurnstileCloudFlareTask (cf_clearance) + +Used for bypassing complex Cloudflare protection involving `cf_clearance` cookie and HTML snapshot. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, TurnstileCloudFlareTask + + async def main(): + client = CapmonsterClient(api_key="") + task = TurnstileCloudFlareTask( + cloudflareTaskType="cf_clearance", + websiteURL="https://example.com", + websiteKey="", + userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", + htmlPageBase64="", + proxy=ProxyPayload( + proxyType="https", + proxyAddress="192.168.1.1", + proxyPort=8000) + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, TurnstileCloudFlareTask, ProxyPayload + + client = CapmonsterClient(api_key="") + task = TurnstileCloudFlareTask( + cloudflareTaskType="cf_clearance", + websiteURL="https://example.com", + websiteKey="", + userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", + htmlPageBase64="", + proxy=ProxyPayload( + proxyType="https", + proxyAddress="192.168.1.1", + proxyPort=8000) + ) + task_id = client.create_task(task=task) + result = client.get_task_result(task_id) + print(result) + ``` + +## reCAPTCHA v3 + +Used for solving score-based reCAPTCHA v3 challenges without requiring a proxy. +You can optionally provide `minScore` and `pageAction` to match expected interaction patterns. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, RecaptchaV3Task + + async def main(): + client = CapmonsterClient(api_key="") + task = RecaptchaV3Task( + websiteURL="https://example.com", + websiteKey="", + minScore=0.5, + pageAction="verify" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result.get("gRecaptchaResponse")) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, RecaptchaV3Task + + client = CapmonsterClient(api_key="") + task_id = client.create_task(RecaptchaV3Task( + websiteURL="https://example.com", + websiteKey="", + minScore=0.5, + pageAction="verify" + )) + result = client.get_task_result(task_id) + print(result.get("gRecaptchaResponse")) + ``` + +## reCAPTCHA v2 Enterprise + +Used for solving Google reCAPTCHA V2 Enterprise challenges. +Optional support for `enterprisePayload`, custom `apiDomain`, and `cookies`. + +=== "Async" + + ```python + import asyncio + from capmonster_python import CapmonsterClient, RecaptchaV2EnterpriseTask + + async def main(): + client = CapmonsterClient(api_key="") + task = RecaptchaV2EnterpriseTask( + websiteURL="https://example.com", + websiteKey="", + enterprisePayload="{\"s\":\"abc123\"}", + cookies="cookie=value;cookie_2=value2" + ) + task_id = await client.create_task_async(task) + result = await client.get_task_result_async(task_id) + print(result.get("gRecaptchaResponse")) + + asyncio.run(main()) + ``` + +=== "Sync" + + ```python + from capmonster_python import CapmonsterClient, RecaptchaV2EnterpriseTask + + client = CapmonsterClient(api_key="") + task_id = client.create_task(RecaptchaV2EnterpriseTask( + websiteURL="https://example.com", + websiteKey="", + enterprisePayload="{\"s\":\"abc123\"}", + cookies="cookie=value;cookie_2=value2" + )) + result = client.get_task_result(task_id) + print(result.get("gRecaptchaResponse")) + ``` diff --git a/docs/gatsby-config.js b/docs/gatsby-config.js deleted file mode 100644 index 77dafbe..0000000 --- a/docs/gatsby-config.js +++ /dev/null @@ -1,53 +0,0 @@ -module.exports = { - siteMetadata: { - siteTitle: `capmonster-python docs`, - defaultTitle: `capmonster-python docs`, - siteTitleShort: `capmonster-python`, - siteDescription: `capmonster-python documentation for capmonster.cloud`, - siteUrl: `https://docs.alperenn.com`, - siteAuthor: `@alperensert`, - siteImage: `/banner.png`, - siteLanguage: `en`, - themeColor: `#8257E6`, - basePath: `/`, - }, - plugins: [ - { - resolve: `@rocketseat/gatsby-theme-docs`, - options: { - configPath: `src/config`, - docsPath: `src/docs`, - yamlFilesPath: `src/yamlFiles`, - repositoryUrl: `https://github.com/jpedroschmitz/rocketdocs`, - baseDir: `examples/gatsby-theme-docs`, - gatsbyRemarkPlugins: [], - }, - }, - { - resolve: `gatsby-plugin-manifest`, - options: { - name: `Rocket Docs`, - short_name: `Rocket Docs`, - start_url: `/`, - background_color: `#ffffff`, - display: `standalone`, - icon: `static/favicon.png`, - }, - }, - `gatsby-plugin-sitemap`, - // { - // resolve: `gatsby-plugin-google-analytics`, - // options: { - // trackingId: `YOUR_ANALYTICS_ID`, - // }, - // }, - `gatsby-plugin-remove-trailing-slashes`, - { - resolve: `gatsby-plugin-canonical-urls`, - options: { - siteUrl: `https://capmonster-python.alperenn.com`, - }, - }, - `gatsby-plugin-offline`, - ], -}; diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..acd0ef2 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,17 @@ +# 🧠 Capmonster Python + +Welcome to the documentation for **Capmonster Python** β€” a modern, fully typed, async-ready SDK +for [Capmonster.Cloud](https://capmonster.cloud/). + +This site will help you integrate with various CAPTCHA challenge types such as reCAPTCHA, Turnstile, GeeTest, +Image-to-Text, and more. + +--- + +## πŸš€ Quick Start + +Jump into your first integration: + +- [Installation](installation.md) +- [Examples](examples.md) +- [API Reference](reference/overview.md) diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..1d4ab1b --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,25 @@ +# πŸ›  Installation + +=== "pip" + + ```bash + pip install capmonster_python + ``` + +=== "pipx" + + ```bash + poetry add capmonster_python + ``` + +=== "poetry" + + ```bash + poetry add capmonster_python + ``` + +!!! warning "To use the legacy v3 syntax" + + ```bash + pip install capmonster-python==3.2 + ``` diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index 62b7b02..0000000 --- a/docs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "gatsby-starter-rocketdocs", - "private": true, - "version": "1.0.0", - "description": "Out of the box Gatsby Starter for creating documentation websites easily and quickly. With support for MDX, code highlight, Analytics, SEO and more", - "author": "JoΓ£o Pedro Schmitz (@jpedroschmitz)", - "license": "MIT", - "starter-name": "gatsby-starter-rocketdocs", - "dependencies": { - "@rocketseat/gatsby-theme-docs": "^3.2.0", - "gatsby": "^4.2.0", - "gatsby-plugin-canonical-urls": "^4.2.0", - "gatsby-plugin-google-analytics": "^4.2.0", - "gatsby-plugin-manifest": "^4.2.0", - "gatsby-plugin-offline": "^5.2.0", - "gatsby-plugin-remove-trailing-slashes": "^4.2.0", - "gatsby-plugin-sitemap": "^5.2.0", - "prop-types": "^15.7.2", - "react": "^17.0.2", - "react-dom": "^17.0.2" - }, - "devDependencies": { - "gh-pages": "^4.0.0", - "yarn-upgrade-all": "^0.7.1" - }, - "keywords": [ - "gatsby", - "gatsby-starter" - ], - "scripts": { - "build": "gatsby build --prefix-paths", - "start": "gatsby develop", - "serve": "gatsby serve", - "clean": "gatsby clean", - "deploy": "gatsby build --prefix-paths && gh-pages -d public" - } -} diff --git a/docs/reference/abstract.md b/docs/reference/abstract.md new file mode 100644 index 0000000..a602da9 --- /dev/null +++ b/docs/reference/abstract.md @@ -0,0 +1,9 @@ +# Abstracts + +::: capmonster_python.tasks.task.VanillaTaskPayload + +::: capmonster_python.tasks.task.TaskPayload + +::: capmonster_python.tasks.task.UserAgentPayload + +::: capmonster_python.tasks.task.ProxyPayload diff --git a/docs/reference/client.md b/docs/reference/client.md new file mode 100644 index 0000000..4030851 --- /dev/null +++ b/docs/reference/client.md @@ -0,0 +1,3 @@ +# πŸ’Ό CapmonsterClient + +::: capmonster_python.CapmonsterClient diff --git a/docs/reference/enterprise.md b/docs/reference/enterprise.md new file mode 100644 index 0000000..67cf123 --- /dev/null +++ b/docs/reference/enterprise.md @@ -0,0 +1,9 @@ +# πŸ›‘οΈ Enterprise + +::: capmonster_python.DataDomeTask + +::: capmonster_python.DataDomeMetadata + +::: capmonster_python.ImpervaTask + +::: capmonster_python.ImpervaTaskMetadata diff --git a/docs/reference/exceptions.md b/docs/reference/exceptions.md new file mode 100644 index 0000000..c68a27a --- /dev/null +++ b/docs/reference/exceptions.md @@ -0,0 +1,7 @@ +# ❗ Exceptions + +::: capmonster_python.CapmonsterException + +::: capmonster_python.CapmonsterAPIException + +::: capmonster_python.CapmonsterValidationException diff --git a/docs/reference/geetest.md b/docs/reference/geetest.md new file mode 100644 index 0000000..5ad44c9 --- /dev/null +++ b/docs/reference/geetest.md @@ -0,0 +1,5 @@ +# 🧠 GeeTest + +::: capmonster_python.GeeTestV3Task + +::: capmonster_python.GeeTestV4Task diff --git a/docs/reference/image.md b/docs/reference/image.md new file mode 100644 index 0000000..03f4cf6 --- /dev/null +++ b/docs/reference/image.md @@ -0,0 +1,8 @@ +# πŸ–ΌοΈ Image Based + +::: capmonster_python.ImageToTextTask + +::: capmonster_python.ComplexImageRecaptchaTask +::: capmonster_python.ComplexImageRecaptchaMetadata + +::: capmonster_python.ComplexImageRecognitionTask diff --git a/docs/reference/miscellaneous.md b/docs/reference/miscellaneous.md new file mode 100644 index 0000000..221e09a --- /dev/null +++ b/docs/reference/miscellaneous.md @@ -0,0 +1,5 @@ +# πŸ§ͺ Miscellaneous + +::: capmonster_python.ProsopoTask + +::: capmonster_python.BasiliskTask diff --git a/docs/reference/overview.md b/docs/reference/overview.md new file mode 100644 index 0000000..d8f0ad0 --- /dev/null +++ b/docs/reference/overview.md @@ -0,0 +1,29 @@ +# πŸ“˜ API Reference + +Welcome to the **Capmonster Python** API reference. + +This section provides detailed documentation for all available task types and core classes in the Capmonster ecosystem. +Whether you're solving reCAPTCHA, Turnstile, or advanced behavioral CAPTCHAs like DataDome or Imperva, this reference +will guide you through the available models, parameters, and behaviors. + +--- + +## Overview + +Capmonster Python v4 is fully typed with [Pydantic](https://docs.pydantic.dev/) and exposes task models via clear class +structures. All classes include: + +- βœ… Type-annotated attributes +- 🧩 Google-style docstrings +- πŸ›  `to_request()` methods for raw dict generation +- πŸ” Sync/Async-ready usage with `CapmonsterClient` + +--- + +## Usage Notes + +- All tasks are **instantiable Pydantic models** +- If you are solving proxy-based CAPTCHAs, configure `proxy` and `userAgent` attributes +- Task classes **do not make API calls** β€” use them with `CapmonsterClient` + +--- diff --git a/docs/reference/platform.md b/docs/reference/platform.md new file mode 100644 index 0000000..bf15bec --- /dev/null +++ b/docs/reference/platform.md @@ -0,0 +1,7 @@ +# 🏦 Platform-Specific + +::: capmonster_python.BinanceTask + +::: capmonster_python.TemuTask + +::: capmonster_python.TenDITask diff --git a/docs/reference/recaptcha.md b/docs/reference/recaptcha.md new file mode 100644 index 0000000..1fd3176 --- /dev/null +++ b/docs/reference/recaptcha.md @@ -0,0 +1,7 @@ +# 🧠 reCAPTCHA + +::: capmonster_python.RecaptchaV2Task + +::: capmonster_python.RecaptchaV2EnterpriseTask + +::: capmonster_python.RecaptchaV3Task diff --git a/docs/reference/turnstile.md b/docs/reference/turnstile.md new file mode 100644 index 0000000..df0e7db --- /dev/null +++ b/docs/reference/turnstile.md @@ -0,0 +1,5 @@ +# ☁️ Turnstile + +::: capmonster_python.TurnstileTask + +::: capmonster_python.TurnstileCloudFlareTask diff --git a/docs/src/@rocketseat/gatsby-theme-docs/text/index.mdx b/docs/src/@rocketseat/gatsby-theme-docs/text/index.mdx deleted file mode 100644 index e88e4c6..0000000 --- a/docs/src/@rocketseat/gatsby-theme-docs/text/index.mdx +++ /dev/null @@ -1,19 +0,0 @@ -# Introduction - -Capmonster is a cloud service for automatic recognition of reCAPTCHA, hCaptcha and other types of captchas. -This is the documentation of [Capmonster.cloud](https://capmonster.cloud) Python3 package. - -## Available Captcha Types - -- Image to Text -- ReCaptcha V2 -- ReCaptcha V2 Enterprise -- FunCaptcha -- HCaptcha -- ReCaptcha V3 -- GeeTest -- Turnstilke Task - -
- -[Get started now!](/installation) diff --git a/docs/src/config/sidebar.yml b/docs/src/config/sidebar.yml deleted file mode 100644 index bb4f6df..0000000 --- a/docs/src/config/sidebar.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Sidebar navigation - -- label: 'Introduction' - link: '/' -- label: 'Installation' - link: '/installation' -- label: Usage - items: - - label: 'Image to Text' - link: '/usage/solve-img-to-text' - - label: 'ReCaptcha v2' - link: '/usage/solve-recap-v2' - - label: 'FunCaptcha' - link: '/usage/solve-funcap' - - label: 'HCaptcha' - link: '/usage/solve-hcaptcha' - - label: 'ReCaptcha v3' - link: '/usage/solve-recap-v3' - - label: 'GeeTest' - link: '/usage/solve-geetest' - - label: 'Turnstile' - link: '/usage/solve-turnstile' - - label: 'Proxy and User Agent' - link: '/usage/proxy-and-ua' -- label: API - items: - - label: class Capmonster - link: '/api/class-capmonster' - - label: class ImageToTextTask - link: '/api/class-img-to-text' - - label: class ReCaptchaV2Task - link: '/api/class-recap-v2' - - label: class GeeTestTask - link: '/api/class-geetest' - - label: class ReCaptchaV3Task - link: '/api/class-recap-v3' - - label: class FunCaptchaTask - link: '/api/class-funcap' - - label: class HCaptchaTask - link: '/api/class-hcap' - - label: class TurnstileTask - link: '/api/class-turnstile' - - label: class Proxy - link: '/api/class-proxy' - - label: class UserAgent - link: '/api/class-useragent' -- label: More - items: - - label: Error Types - link: /error-types - - label: No Cache - link: /no-cache - - label: Examples - link: /examples - - label: 'Github' - link: https://github.com/alperensert/capmonster_python diff --git a/docs/src/docs/api/class-capmonster.mdx b/docs/src/docs/api/class-capmonster.mdx deleted file mode 100644 index d412782..0000000 --- a/docs/src/docs/api/class-capmonster.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: class Capmonster ---- - -## Methods -### get_balance -- Does not have any specific parameter, returns the current balance of specified api key. - -### get_task_result -- Get task's result. Returns a dictionary if task is ready, else returns `false` - -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|task_id|Integer|Yes|-|ID which was obtained in createTask method| - -### join_task_result -- Get task's result. Returns a dictionary if task is ready, else raise CapmonsterException with error code `MAXIMUM_TIME_EXCEED` - -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|task_id|Integer|Yes|-|ID which was obtained in createTask method| -|maximum_time|Integer|No|120| - -### join_task_result_async -- Get task's result. Returns a dictionary if task is ready, else raise CapmonsterException with error code `MAXIMUM_TIME_EXCEED` - -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|task_id|Integer|Yes|-|ID which was obtained in createTask method| -|maximum_time|Integer|No|120| - -> All task classes are inherits the _Capmonster_ class. \ No newline at end of file diff --git a/docs/src/docs/api/class-funcap.mdx b/docs/src/docs/api/class-funcap.mdx deleted file mode 100644 index e2251ab..0000000 --- a/docs/src/docs/api/class-funcap.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: class FunCaptchaTask ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of a webpage with FunCaptcha| -|website_public_key|String|Yes|-|FunCaptcha website key

_(div id="funcaptcha" data-pkey="THAT_ONE")_| -|api_js_subdomain|String|No|-|A special subdomain of funcaptcha.com, from which the JS captcha widget should be loaded. Most FunCaptcha installations work from shared domains, so this option is only needed in certain rare cases.| -|data_blob|String|No|-|Additional parameter that may be required by Funcaptcha implementation.

Use this property to send "blob" value as a stringified array. See example how it may look like.
_{"\blob\":\"HERE_COMES_THE_blob_VALUE\"}_| -|cookies|Dict, List, String|No|-|Additional cookies which we must use during interaction with target page or Google

If you are pass the cookies as string, here is the format: cookiename1=cookievalue1; cookiename2=cookievalue2| -|no_cache|Boolean|No|-|You receive a token, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, e.g. in one case out of 10 (_the percentage of success in your case may be different_)| - -### Inherited methods -- See [_Capmonster_](/api/class-capmonster) class for inherited methods. -- See [_Proxy_](/api/class-proxy) class for inherited methods. -- See [_UserAgent_](/api/class-useragent) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-geetest.mdx b/docs/src/docs/api/class-geetest.mdx deleted file mode 100644 index 0fd3d8b..0000000 --- a/docs/src/docs/api/class-geetest.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: class GeeTestTask ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of the page on which the captcha is ricognized| -|gt|String|Yes|-|The GeeTest identifier key for the domain. Static value, rarely updated.| -|challenge|String|Yes|-|A dynamic key.
Each time our API is called, we need to get a new key value. If the captcha is loaded on the page, then the challenge value is no longer valid.
It is necessary to examine the requests and find the one in which this value is returned and, before each creation of the recognition task, execute this request and parse the challenge from it.| -|api_server_subdomain|String|No|-|Optional parameter. May be required for some sites.| -|get_lib|String|No|-|Optional parameter. May be required for some sites.
Send JSON as a string.| - -### Inherited methods -- See [_Capmonster_](/api/class-capmonster) class for inherited methods. -- See [_Proxy_](/api/class-proxy) class for inherited methods. -- See [_UserAgent_](/api/class-useragent) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-hcap.mdx b/docs/src/docs/api/class-hcap.mdx deleted file mode 100644 index fa82dc4..0000000 --- a/docs/src/docs/api/class-hcap.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: class HCaptchaTask ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods - -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of a webpage with hCaptcha| -|website_key|String|Yes|-|hCaptcha website key| -|is_invisible|Boolean|No|-|Use `True` for invisible version of hcaptcha| -|custom_data|String|No|-|Custom data that is used in some implementations of hCaptcha, mostly with isInvisible=true. In most cases you see it as rqdata inside network requests

**IMPORTANT:** You **MUST** provide an user agent if you submit captcha with data parameter. The value should match the user agent you use when interacting with the target website.| -|cookies|Dict, List, String|No|-|Additional cookies which we must use during interaction with target page or Google

If you are pass the cookies as string, here is the format: cookiename1=cookievalue1; cookiename2=cookievalue2| -|no_cache|Boolean|No|-|You receive a token, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, e.g. in one case out of 10 (_the percentage of success in your case may be different_)| - -### Inherited methods -- See [_Capmonster_](/api/class-capmonster) class for inherited methods. -- See [_Proxy_](/api/class-proxy) class for inherited methods. -- See [_UserAgent_](/api/class-useragent) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-img-to-text.mdx b/docs/src/docs/api/class-img-to-text.mdx deleted file mode 100644 index 7e2c4a2..0000000 --- a/docs/src/docs/api/class-img-to-text.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: class ImageToTextTask ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods - -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|image_path|String|Yes *|-|Automatically encode with base64| -|base64_encoded_image|String|Yes *|-|Image body encoded in base64. Make sure to send it without line breaks and as string| -|module|String|No|-|Name of recognizing module e.g _yandex_ -|recognizing_threshold|Integer|No|-|Captcha recognition threshold with a possible value from 0 to 100. For example, if a value of 90 was sent to the system, and the problem was solved with confidence of 80, then the money for the solution will not be charged. In this case, the user will receive an ERROR_CAPTCHA_UNSOLVABLE exception| -|case|Boolean|No|-|Whether to consider case when deciding or not| -|numeric|Integer|No|0|**1** - if the captcha consists of numbers only| -|math|Boolean|No|-|**true** - captcha requires a mathematical action (e.g captcha 2 + 6 = will return the value 8)| - -### Inherited methods -See [_Capmonster_](/api/class-capmonster) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-proxy.mdx b/docs/src/docs/api/class-proxy.mdx deleted file mode 100644 index 39303ad..0000000 --- a/docs/src/docs/api/class-proxy.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: class Proxy ---- - -## Methods -### set_proxy -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|proxy_type|String|Yes|-|Type of the proxy

**http** - usual http/https proxy
**https** - try this only if "http" doesn't work (required by some custom proxy servers)
**socks4** - socks4 proxy
**socks5** - socks5 proxy
| -|proxy_address|String|Yes|-|Proxy IP address IPv4/IPv6. Not allowed to use:

  • host names instead of IPs
  • transparent proxies (where client IP is visible)
  • proxies from local networks (192.., 10.., 127...)
| -|proxy_port|Integer|Yes|-|Proxy port| -|proxy_login|String|No *|-|Login for proxy which requires authorizaiton (basic)| -|proxy_password|String|No *|-|Proxy password| - -\* If your proxy isn't authorized by IP you must pass the both of them. But the proxy is authorized by IP, then be sure to add **116.203.55.208** to the white list. - -### method disable_proxy -Doesn't have any specific parameters, it's disables and clear the proxy. \ No newline at end of file diff --git a/docs/src/docs/api/class-recap-v2.mdx b/docs/src/docs/api/class-recap-v2.mdx deleted file mode 100644 index 17ebd76..0000000 --- a/docs/src/docs/api/class-recap-v2.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: class ReCaptchaV2Task ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of a webpage with Google ReCaptcha| -|website_key|String|Yes|-|Recaptcha website key _(div class="g-recaptcha" data-sitekey="THAT_ONE")_| -|cookies|Dict, List, String|No|-|Additional cookies which we must use during interaction with target page or Google

If you are pass the cookies as string, here is the format: cookiename1=cookievalue1; cookiename2=cookievalue2| -|recaptcha_s_value|String|No|-|Some custom implementations may contain additional "data-s" parameter in ReCaptcha2 div, which is in fact a one-time token and must be grabbed every time you want to solve a ReCaptcha2.

_div class="g-recaptcha" data-sitekey="some sitekey" data-s="THIS_ONE"_| -|no_cache|Boolean|No|-|You receive a token, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, e.g. in one case out of 10 (_the percentage of success in your case may be different_)| - -### Inherited methods -- See [_Capmonster_](/api/class-capmonster) class for inherited methods. -- See [_Proxy_](/api/class-proxy) class for inherited methods. -- See [_UserAgent_](/api/class-useragent) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-recap-v3.mdx b/docs/src/docs/api/class-recap-v3.mdx deleted file mode 100644 index fc9185c..0000000 --- a/docs/src/docs/api/class-recap-v3.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: class ReCaptchaV3Task ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods - -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of a webpage with Google ReCaptcha| -|website_key|String|Yes|-|Recaptcha website key

_(google.com/recaptcha/api.js?render="THAT_ONE")_| -|minimum_score|Float (double)|No|0.3|Value from 0.1 to 0.9| -|page_action|String|No|verify|Widget action value. Website owner defines what user is doing on the page through this parameter.

_e.g. grecaptcha.execute('site_key', {action:'login_test'})_| -|no_cache|Boolean|No|-|You receive a token, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, e.g. in one case out of 10 (_the percentage of success in your case may be different_)| - -### Inherited methods -See [_Capmonster_](/api/class-capmonster) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-turnstile.mdx b/docs/src/docs/api/class-turnstile.mdx deleted file mode 100644 index b68c0a2..0000000 --- a/docs/src/docs/api/class-turnstile.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: class TurnstileTask ---- - -## Constructor -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|client_key|String|Yes|-|Your unique key to solve captchas| - -## Methods -### create_task -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|website_url|String|Yes|-|Address of a webpage with Google ReCaptcha Enterprise| -|website_key|String|Yes|-|Turnstile key| -|no_cache|Boolean|No|-|You receive a token, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, e.g. in one case out of 10 (_the percentage of success in your case may be different_)| - -### Inherited methods -- See [_Capmonster_](/api/class-capmonster) class for inherited methods. -- See [_Proxy_](/api/class-proxy) class for inherited methods. \ No newline at end of file diff --git a/docs/src/docs/api/class-useragent.mdx b/docs/src/docs/api/class-useragent.mdx deleted file mode 100644 index 99c44ab..0000000 --- a/docs/src/docs/api/class-useragent.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: class UserAgent ---- - -## Methods - -### set_user_agent -|Parameter|Type|Required|Default value|Purpose| -|---------|----|--------|-------------|-------| -|user_agent|String|Yes|-|Add user agent to task| - -### reset_user_agent -Doesn't have any specific parameters, it's disables and clear the user agent. \ No newline at end of file diff --git a/docs/src/docs/error-types.mdx b/docs/src/docs/error-types.mdx deleted file mode 100644 index 0743350..0000000 --- a/docs/src/docs/error-types.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Error Types ---- - -## Error List -|Error Code|Error Description| -|----------|-----------------| -|ERROR_KEY_DOES_NOT_EXIST|Account authorization key not found in the system or has incorrect format (length is not)| -|ERROR_ZERO_CAPTCHA_FILESIZE|The size of the captcha you are uploading is less than 100 bytes.| -|ERROR_TOO_BIG_CAPTCHA_FILESIZE|The size of the captcha you are uploading is more than 50,000 bytes.| -|ERROR_ZERO_BALANCE|Account has zero balance| -|ERROR_IP_NOT_ALLOWED|Request with current account key is not allowed from your IP| -|ERROR_CAPTCHA_UNSOLVABLE|This type of captchas is not supported by the service or the image does not contain an answer, perhaps it is too noisy. It could also mean that the image is corrupted or was incorrectly rendered.| -|ERROR_NO_SUCH_CAPCHA_ID, WRONG_CAPTCHA_ID|The captcha that you are requesting was not found. Make sure you are requesting a status update only within 5 minutes of uploading.| -|CAPTCHA_NOT_READY|The captcha has not yet been solved| -|ERROR_IP_BANNED|You have exceeded the limit of requests with the wrong api key, check the correctness of your api key in the control panel and after some time, try again| -|ERROR_NO_SUCH_METHOD|This method is not supported or empty| -|ERROR_TOO_MUCH_REQUESTS|You have exceeded the limit of requests to receive an answer for one task| -|ERROR_MAXIMUM_TIME_EXCEED|Captcha response could not be received at the specified time| -|ERROR_NOTHING_GIVEN|You have to give image_path or base64_encoded_image at least| - -### Explanation for ERROR_IP_BANNED -If you get this error, you can see the reason from [here](https://capmonster.cloud/BanEvents/History). - -The main reasons for getting a ban: -- **KeyDoesntExist:** Multiple requests without a key or with an invalid key -- **ZeroBalance:** Multiple requests with zero balance -- **WrongTaskId:** When exceeding the limit of the 120 requests per task / 1 min -- **BadProxy:** multiple requests with a banned proxy - -> Note: Please do not forget, users receive a ban for repeated this actions for a limited period of time. - -#### When will the ban removed? -The duration of the block is **30 minutes**, _provided that you do not continue to break the rules described above_. \ No newline at end of file diff --git a/docs/src/docs/examples.mdx b/docs/src/docs/examples.mdx deleted file mode 100644 index 7bfd73a..0000000 --- a/docs/src/docs/examples.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Examples ---- - -To run the examples in your local machine, please do the followings: - -## Steps - -1. Create a folder and clone the repository - - ```sh - mkdir capmonster-python - cd capmonster-python - git init - git clone https://github.com/alperensert/capmonster_python.git - ``` -2. Go to examples folder and install the requirements (examples only) - - ```sh - cd examples - pip install -r requirements.txt - ``` -3. Then set 2 environment variables for correctly run the examples, _API_KEY_ and _HEADLESS_ - 1. Api key is your unique key to solve captchas - 2. Headless is needed for running selenium examples. - -4. Now you are ready to run examples, e.g. - - ```sh - python recaptchav2_selenium.py - ``` - -> Note: If you want to run selenium examples, Firefox must be installed - -- All examples are [here](https://github.com/alperensert/capmonster_python/tree/master/tests) diff --git a/docs/src/docs/installation.mdx b/docs/src/docs/installation.mdx deleted file mode 100644 index 66da6d8..0000000 --- a/docs/src/docs/installation.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: 'Installation' -description: Learn how to install package ---- - -```bash -pip install capmonster-python -``` - -> Please do not forget. Package is only compatible with Python >=3 versions. diff --git a/docs/src/docs/no-cache.mdx b/docs/src/docs/no-cache.mdx deleted file mode 100644 index 32eaa7d..0000000 --- a/docs/src/docs/no-cache.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: No Cache ---- - -This page is explanation of _no_cache_ parameter. - -## What if the site only accepts a portion of the tokens from Capmonster.cloud? -You receive a token from Capmonster Cloud, send it to the site, but the site rejects it. Moreover, sometimes the site can accept a token, for example, in one case out of 10 (the percentage of success in your case may be different). - -In this case, the `no_cache` parameter can help you. - -## Tasks that support this parameter -- Recaptcha v2 -- Recaptcha v3 -- Funcaptcha -- HCaptcha \ No newline at end of file diff --git a/docs/src/docs/usage/proxy-and-ua.mdx b/docs/src/docs/usage/proxy-and-ua.mdx deleted file mode 100644 index 02b6415..0000000 --- a/docs/src/docs/usage/proxy-and-ua.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Proxy and User Agent -description: Learn how to implement proxy and user agent to a task ---- - -You can use proxy and user agent in supported tasks. - -## Supported task list -- Recaptcha v2 -- Fun captcha -- HCaptcha -- GeeTest -- Turnstile - -> For GeeTest and HCaptcha, proxies with IP authorization are not yet supported.
-> For others, if the proxy is authorized by IP, then be sure to add **116.203.55.208** to the white list. - -## ReCaptcha v2 Usage -```py title=recap_v2_proxy.py -from capmonster_python import RecaptchaV2Task - -capmonster = RecaptchaV2Task("API_KEY") -capmonster.set_proxy("http", "8.8.8.8", 8080) -capmonster.set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) -``` - -## FunCaptcha Usage -```py title=funcap_proxy.py -from capmonster_python import FuncaptchaTask - -capmonster = FuncaptchaTask("API_KEY") -capmonster.set_proxy("http", "8.8.8.8", 8080) -capmonster.set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0") -task_id = capmonster.create_task("website_url", "website_public_key") -result = capmonster.join_task_result(task_id) -print(result.get("token")) -``` - -## HCaptcha Usage -```py title=hcap_proxy.py -from capmonster_python import HCaptchaTask - -capmonster = HCaptchaTask("API_KEY") -capmonster.set_proxy("http", "8.8.8.8", 8080) -capmonster.set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) -``` - -## GeeTest Usage -```py title=geetest_proxy.py -from capmonster_python import GeeTestTask - -capmonster = GeeTestTask("API_KEY") -capmonster.set_proxy("http", "8.8.8.8", 8080) -capmonster.set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0") -task_id = capmonster.create_task("website_url", "gt", "challenge") -result= capmonster.join_task_result(task_id) -print(result.get("challenge")) -print(result.get("seccode")) -print(result.get("validate")) -``` - -## Turnstile Usage -```py title=turnstile_proxy.py -from capmonster_python import TurnstileTask - -capmonster = TurnstileTask("API_KEY") -capmonster.set_proxy("http", "8.8.8.8", 8080) -capmonster.set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("token")) -``` - diff --git a/docs/src/docs/usage/solve-funcap.mdx b/docs/src/docs/usage/solve-funcap.mdx deleted file mode 100644 index ee5280b..0000000 --- a/docs/src/docs/usage/solve-funcap.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Solve FunCaptcha -description: Learn how to solve funcaptcha ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -## What you need -1. Website's public key -2. Website url - -### Get public website key -Mostly, you can find the key in _data-pkey_ attribute. -```html -
-```` - -## Solve - -```py title=solve_funcaptcha.py -from capmonster_python import FuncaptchaTask - -capmonster = FuncaptchaTask("API_KEY") -task_id = capmonster.create_task("website_url", "website_public_key") -result = capmonster.join_task_result(task_id) -print(result.get("token")) -```` \ No newline at end of file diff --git a/docs/src/docs/usage/solve-geetest.mdx b/docs/src/docs/usage/solve-geetest.mdx deleted file mode 100644 index 953d6a2..0000000 --- a/docs/src/docs/usage/solve-geetest.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Solve GeeTest -description: Learn how to solve GeeTest ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -## What you need -1. GeeTest identifier key (a.k.a. _gt_) -2. Challenge key -2. Website url - -### How to get you needs? -- The gt, challenge and geetestApiServerSubdomain parameters are most often found inside the initGeetest JavaScript function. -- Also you can see in the HTML code of the page. -You can find it in the **script** block, which appears after the page is fully loaded in the browser. -![geetest](/geetest.jpg) - -## Solve - -```py title=solve_geetest.py -from capmonster_python import GeeTestTask - -capmonster = GeeTestTask("API_KEY") -task_id = capmonster.create_task("website_url", "gt", "challenge") -result= capmonster.join_task_result(task_id) -print(result.get("challenge")) -print(result.get("seccode")) -print(result.get("validate")) -``` - -## Important Note -> Keep in mind, the _gt_ challenge is rarely updated. -> But challenge value is always changing when everytime you see a GeeTest Captcha. \ No newline at end of file diff --git a/docs/src/docs/usage/solve-hcaptcha.mdx b/docs/src/docs/usage/solve-hcaptcha.mdx deleted file mode 100644 index f023807..0000000 --- a/docs/src/docs/usage/solve-hcaptcha.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Solve HCaptcha -description: Learn how to solve HCaptcha ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -## What you need -1. Website key -2. Website url - -## Solve - -```py title=solve_hcaptcha.py -from capmonster_python import HCaptchaTask - -capmonster = HCaptchaTask("API_KEY") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) -``` \ No newline at end of file diff --git a/docs/src/docs/usage/solve-img-to-text.mdx b/docs/src/docs/usage/solve-img-to-text.mdx deleted file mode 100644 index 3b5241e..0000000 --- a/docs/src/docs/usage/solve-img-to-text.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Solve Image to Text Captcha -description: Learn how to solve image to text captchas. ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -Image to Text Captcha's can be send with two different ways. - -### Send image with ImagePath - -If you have the image on your local path, or if you can download it, use _image_path_ way. - -```py title=image_to_text_with_image_path.py -from capmonster_python import ImageToTextTask - -capmonster = ImageToTextTask("API_KEY") -task_id = capmonster.create_task(image_path="img.png") -result = capmonster.join_task_result(task_id) -print(result.get("text")) -``` - -### Send image as Base64 Encoded - -If you have to handle the captchas real-time, -you can download the image and convert it to Base64. - -```python title=image_to_text_base64_encoded.py -from capmonster_python import ImageToTextTask - -capmonster = ImageToTextTask("API_KEY") -task_id = capmonster.create_task(base64_encoded_image="base64encodedimage_as_string") -result = capmonster.join_task_result(task_id) -print(result.get("text")) -``` - -> Make sure to send it without line breaks while using Base64 Encoded way. \ No newline at end of file diff --git a/docs/src/docs/usage/solve-recap-v2.mdx b/docs/src/docs/usage/solve-recap-v2.mdx deleted file mode 100644 index 509db3c..0000000 --- a/docs/src/docs/usage/solve-recap-v2.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Solve ReCaptcha V2 -description: Learn how to solve re-captcha v2 ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -ReCaptcha v2 is a captcha service implementation from Google. - -## What you need -1. Website's captcha key -2. Website url - -### Get website key -Mostly, you can find website key inside the _g-recaptcha_ div. -```html -
-```` - -## Solve - -```py title=solve_recaptchav2.py -from capmonster_python import RecaptchaV2Task - -capmonster = RecaptchaV2Task("API_KEY") -task_id = capmonster.create_task("website_url", "website_key") -result = capmonster.join_task_result(task_id) -print(result.get("gRecaptchaResponse")) -```` \ No newline at end of file diff --git a/docs/src/docs/usage/solve-recap-v3.mdx b/docs/src/docs/usage/solve-recap-v3.mdx deleted file mode 100644 index 081eca5..0000000 --- a/docs/src/docs/usage/solve-recap-v3.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Solve ReCaptcha v3 -description: Learn how to solve ReCaptcha V3 ---- - -> First of all, you need an API key to work. You can get one from [here](https://capmonster.cloud) - -## What you need -1. Website key -2. Website url - -### Get website key -Mostly, you can find the site key in _api.js_'s query parameters. -```html -