From a76f33af4292eb1609a1aa732fd39a92d3795d3e Mon Sep 17 00:00:00 2001 From: Matthew Lugo Date: Sat, 8 May 2021 13:12:25 -0400 Subject: [PATCH] 1.1.0 In version 1.1.0: - Added new `NoHarvesterException` exception - Fixed exception handling - Fixed typo in capmonster module - Updated docstring - HCaptcha support (Anticaptcha, Capmonster, 2captcha) - Updated README (documentation): - [How to use] - Description - [Supported Sites] - Captcha & Task Types - [Exceptions] - Added new exception to chart, Added extra exmaple - [TO DO] - Updated TODO list --- README.md | 37 ++++++++++++++++++++++++++----------- captchatools/__init__.py | 17 +++++++++-------- captchatools/anticaptcha.py | 5 +++-- captchatools/capmonster.py | 5 +++-- captchatools/exceptions.py | 19 +++++++++++++------ captchatools/harvesters.py | 7 +++++++ captchatools/twocap.py | 11 +++++++++-- setup.py | 2 +- 8 files changed, 71 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index b416227..ae0d395 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ Python module to help solve captchas with Capmonster, 2Captcha and Anticaptcha A ```python pip3 install captchatools ``` +##### To update +```python +pip3 install -U captchatools +``` # How to use ```python @@ -23,12 +27,12 @@ captcha_answer = solver.get_token() | :-------------: |:-------------:| :-----:| :-----:| :-----:| | api_key | true | String| -| The API Key for the captcha solving site| | solving_site| true| String (name of site) or int (site ID) | "capmonster"| Captcha solving site| -| sitekey| true | String | - | Google sitekey from the site where captcha is loaded| +| sitekey| true | String | - | Sitekey from the site where captcha is loaded| | captcha_url | true| String | - | URL where the captcha is located| -| captcha_type| false| String | "v2" | Either captcha v2 or v3| -| invisible_captcha| false | bool | false | If the captcha is invisible or not| -| min_score | false | double |0.7 | Minimum score for v3 captchas| -| action | false | String | "verify" | Action that is associated with the v3 captcha| +| captcha_type| false| String | "v2" | Type of captcha you are solving. Either captcha `v2`, `v3` or `hcaptcha` (`hcap` works aswell)| +| invisible_captcha| false | bool | false | If the captcha is invisible or not.
__This param is only required when solving invisible captchas__| +| min_score | false | double |0.7 | Minimum score for v3 captchas.
__This param is only required when solving V3 and it needs a higher / lower score__| +| action | false | String | "verify" | Action that is associated with the V3 captcha.
__This param is only required when solving V3 captchas__| # Supported Sites @@ -37,11 +41,11 @@ captcha_answer = solver.get_token() - **[Anticaptcha](https://www.anti-captcha.com/)** ##### Site-Specific Support: -| Site |Site ID| Captcha Types | Task Types | +| Site |Site ID| Captcha Types Supported | Task Types Supported| | :-------------: |:-------------:|:-------------:| :-----:| -| Capmonster |1| Recaptcha V2, Recaptcha V3 | RecaptchaV2TaskProxyless, RecaptchaV3TaskProxyless | -| Anticaptcha |2| Recaptcha V2, Recaptcha V3 | RecaptchaV2TaskProxyless, RecaptchaV3TaskProxyless | -| 2Captcha |3| Recaptcha V2, Recaptcha V3 | - | +| Capmonster |1| Recaptcha V2,
Recaptcha V3,
HCaptcha | RecaptchaV2TaskProxyless,
RecaptchaV3TaskProxyless,
HCaptchaTaskProxyless | +| Anticaptcha |2| Recaptcha V2,
Recaptcha V3,
HCaptcha | RecaptchaV2TaskProxyless,
RecaptchaV3TaskProxyless,
HCaptchaTaskProxyless | +| 2Captcha |3| Recaptcha V2,
Recaptcha V3,
HCaptcha | - | # Recommendations @@ -54,7 +58,8 @@ captcha_answer = solver.get_token() | :--------:| :-----:| | `NoBalanceException` | Balance is below 0 for captcha solving site| | `WrongAPIKeyExceptionException` | Incorrect API Key for captcha solving site| -| `WrongSitekeyException` | Incorrect Google sitekey | +| `WrongSitekeyException` | Incorrect sitekey | +| `NoHarvesterException` | When the user did not / incorrectly chose a captcha harvester. Refer to the [guide](https://github.com/Matthew17-21/Captcha-Tools#how-to-use) | ```python from captchatools import captcha_harvesters, exceptions as captchaExceptions @@ -63,6 +68,15 @@ try: except captchaExceptions.NoBalanceException: print("No balance.") ``` +or +```python +import captchatools +try: + ... +except captchatools.NoBalanceException: + print("No balance.") +``` + # TO DO 1. [] Document code better @@ -85,4 +99,5 @@ except captchaExceptions.NoBalanceException: * [] User Agent Support * [] Different type of captchas 5. [] Add DeathByCaptcha -6. [] More defined exceptions \ No newline at end of file +6. [] Release in Go +7. [] Allow for refunds \ No newline at end of file diff --git a/captchatools/__init__.py b/captchatools/__init__.py index 8433253..e4ae0e2 100644 --- a/captchatools/__init__.py +++ b/captchatools/__init__.py @@ -1,15 +1,14 @@ ''' -Library for solving captchas! -~~~~~~~~~~~~~~~~~~~~~ +All-in-one library for solving captchas! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ How to use: ->>> import captcha_harvesters ->>> solver = captcha_harvesters.captcha_harvesters() +>>> import captchatools +>>> solver = captchatools.captcha_harvesters(solving_site="capmonster", api_key="YOUR API KEY", sitekey="SITEKEY", captcha_url="https://www.google.com/recaptcha/api2/demo") >>> captcha_answer = solver.get_token() or - ->>> from captcha_harvesters import captcha_harvesters, exceptions ->>> solver = captcha_harvesters() +>>> from captchatools import captcha_harvesters, exceptions +>>> solver = captcha_harvesters(solving_site=1, api_key="YOUR API KEY", sitekey="SITEKEY", captcha_url="https://www.google.com/recaptcha/api2/demo") >>> captcha_answer = solver.get_token() Sites: @@ -18,4 +17,6 @@ 3 = 2captcha ''' from .harvesters import captcha_harvesters -from . import exceptions \ No newline at end of file +from .exceptions import( + WrongAPIKeyException, NoBalanceException, WrongSitekeyException, NoHarvesterException +) \ No newline at end of file diff --git a/captchatools/anticaptcha.py b/captchatools/anticaptcha.py index c71cadc..430209d 100644 --- a/captchatools/anticaptcha.py +++ b/captchatools/anticaptcha.py @@ -41,6 +41,9 @@ def get_id(self) -> int: payload["task"]["type"] = "RecaptchaV3TaskProxyless" payload["task"]["minScore"] = self.user_data.min_score payload["task"]["pageAction"] = self.user_data.action + + elif self.user_data.captcha_type == "hcap" or self.user_data.captcha_type == "hcaptcha": + payload["task"]["type"] = "HCaptchaTaskProxyless" # Get the Queue ID b sending a POST request to their API while True: @@ -58,14 +61,12 @@ def get_id(self) -> int: elif resp["errorCode"] == "ERROR_KEY_DOES_NOT_EXIST": # Throw Exception raise captchaExceptions.WrongAPIKeyException() - except captchaExceptions.NoBalanceException: raise captchaExceptions.NoBalanceException() except captchaExceptions.WrongSitekeyException: raise captchaExceptions.WrongSitekeyException() except captchaExceptions.WrongAPIKeyException: raise captchaExceptions.WrongAPIKeyException() - except Exception: pass diff --git a/captchatools/capmonster.py b/captchatools/capmonster.py index 47a3ed9..2de8487 100644 --- a/captchatools/capmonster.py +++ b/captchatools/capmonster.py @@ -2,7 +2,7 @@ from . import exceptions as captchaExceptions import time -BASEURL = " https://api.capmonster.cloud" +BASEURL = "https://api.capmonster.cloud" # There's others way we could've done this, @@ -41,6 +41,8 @@ def get_id(self) -> int: payload["task"]["type"] = "RecaptchaV3TaskProxyless" payload["task"]["minScore"] = self.user_data.min_score payload["task"]["pageAction"] = self.user_data.action + elif self.user_data.captcha_type == "hcap" or self.user_data.captcha_type == "hcaptcha": + payload["task"]["type"] = "HCaptchaTaskProxyless" # Get the Queue ID b sending a POST request to their API while True: @@ -67,7 +69,6 @@ def get_id(self) -> int: raise captchaExceptions.WrongSitekeyException() except captchaExceptions.WrongAPIKeyException: raise captchaExceptions.WrongAPIKeyException() - except Exception: pass diff --git a/captchatools/exceptions.py b/captchatools/exceptions.py index f3d1676..b0606b4 100644 --- a/captchatools/exceptions.py +++ b/captchatools/exceptions.py @@ -3,21 +3,28 @@ class WrongAPIKeyException(Exception): ''' This exception gets thrown when the user provides a wrong API Key ''' - def __init__(self): - super().__init__() + def __init__(self, message="[captchatools] Incorrect API key for the captcha solving site"): + super(WrongAPIKeyException, self).__init__(message) class NoBalanceException(Exception): ''' This exception gets thrown when there is no more funds available for the provider ''' - def __init__(self): - super().__init__() + def __init__(self, message="[captchatools] No balance available"): + super(NoBalanceException, self).__init__(message) class WrongSitekeyException(Exception): ''' This exception gets thrown when the user provides a wrong google sitekey ''' - def __init__(self): - super().__init__() + def __init__(self, message="[captchatools] Incorrect google sitekey"): + super(WrongSitekeyException, self).__init__(message) + +class NoHarvesterException(Exception): + ''' + This exception gets thrown when a user doesn't properly set a harvester. + ''' + def __init__(self, message="[captchatools] No captcha harvester selected"): + super(NoHarvesterException, self).__init__(message) \ No newline at end of file diff --git a/captchatools/harvesters.py b/captchatools/harvesters.py index 8b3e377..2aedb42 100644 --- a/captchatools/harvesters.py +++ b/captchatools/harvesters.py @@ -1,6 +1,7 @@ from .twocap import Twocap from .anticaptcha import Anticap from .capmonster import Capmonster +from .exceptions import NoHarvesterException class captcha_harvesters: def __init__( self, solving_site=1, @@ -29,6 +30,12 @@ def __init__( self, solving_site=1, #Get Token from 2captcha API elif self.solving_site == 3 or str(self.solving_site).lower() == "2captcha": self.harvester = Twocap(self) + else: + raise NoHarvesterException( + "No captcha harvester was selected. Double check you entered the site name correctly " + + + "|| Double check the site id is type int" + ) def get_token(self): ''' diff --git a/captchatools/twocap.py b/captchatools/twocap.py index 2d29874..c49e687 100644 --- a/captchatools/twocap.py +++ b/captchatools/twocap.py @@ -19,7 +19,7 @@ def get_token(self) -> str: def get_id(self) -> int: payload = { "key": self.user_data.api_key, - "method": "userrecaptcha", + "method": "userrecaptcha", # Because V2 recaptcha is defaulted on init, I'll leave this "googlekey": self.user_data.sitekey, "pageurl":self.user_data.captcha_url, "json": 1 @@ -33,6 +33,13 @@ def get_id(self) -> int: payload["version"] = "v3" payload["action"] = self.user_data.action payload["min_score"] = self.user_data.min_score + + elif self.user_data.captcha_type == "hcap" or self.user_data.captcha_type == "hcaptcha": + payload["method"] = "hcaptcha" + # We need to remove the "googlekey" ket from the payload + # And replace it with "sitekey" + payload.pop("googlekey") + payload["sitekey"] = self.user_data.sitekey while True: try: @@ -80,4 +87,4 @@ def get_answer(self, queue_id) -> str: except KeyError: self.get_token() except Exception: - pass \ No newline at end of file + pass diff --git a/setup.py b/setup.py index a6a4333..951f5ee 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from io import open PACKAGE_NAME = "captchatools" -VERSION = "1.0.0" +VERSION = "1.1.0" SHORT_DESCRIPTION = "Python module to help solve captchas with Capmonster, 2captcha and Anticaptcha API's!" GITHUB_URL = "https://github.com/Matthew17-21/Captcha-Tools"