diff --git a/README.md b/README.md index a9bf13e..978d20e 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ def main(): - **[2Captcha](https://www.2captcha.com/)** - **[Anticaptcha](https://www.anti-captcha.com/)** - **[Capsolver](https://www.capsolver.com/)** +- **[CaptchaAI](https://captchaai.com/)** ### Site-Specific Support: | Site | Site ID |Captcha Types Supported | Task Types Supported| @@ -121,6 +122,8 @@ def main(): | Capmonster | captchatools.CapmonsterSite| Image captchas,
Recaptcha V2,
Recaptcha V3,
HCaptcha | ImageToTextTask,
NoCaptchaTask,
NoCaptchaTaskProxyless,
RecaptchaV3TaskProxyless,
HCaptchaTaskProxyless | | Anticaptcha | captchatools.AnticaptchaSite| Image captchas,
Recaptcha V2,
Recaptcha V3,
HCaptcha | ImageToTextTask,
RecaptchaV2Task
RecaptchaV2TaskProxyless,
RecaptchaV3TaskProxyless,
HCaptchaTaskProxyless | | 2Captcha | captchatools.TwoCaptchaSite| Image captchas,
Recaptcha V2,
Recaptcha V3,
HCaptcha | - | +| Capsolver | captchatools.CapsolverSite| Image captchas,
Recaptcha V2,
Recaptcha V3,
HCaptcha | - | +| CaptchaAI | captchatools.CaptchaAISite| Image captchas,
Recaptcha V2,
Recaptcha V3,
HCaptcha | - | @@ -145,7 +148,7 @@ from captchatools import new_harvester, exceptions as captchaExceptions, def main(): try: harvester = new_harvester() - token harvester.get_token() + token = harvester.get_token() except captchaExceptions.NoHarvesterException: print("I need to set my captcha harvester!") ``` @@ -153,6 +156,11 @@ def main(): # Changelog +### 1.4.1 +##### What's new +1. Added CaptchaAI +2. Removed internal redundant code +3. Fix creating a new harvester if pass in the ID ### 1.3.0 ##### What's new 1. Get Balance Support diff --git a/captchatools/__init__.py b/captchatools/__init__.py index c24f399..913b6de 100644 --- a/captchatools/__init__.py +++ b/captchatools/__init__.py @@ -15,14 +15,17 @@ 1 = Capmonster 2 = Anticaptcha 3 = 2captcha +4 = Capsolver +5 = CaptchaAI ''' -__version__ = "2.0.0" +__version__ = "1.4.1" __author__ = "Matthew17-21" __license__ = "MIT" from abc import ABC, abstractmethod from typing import Optional from . import exceptions as captchaExceptions +from warnings import warn class Harvester(ABC): ''' Represents a captcha harvester. @@ -72,8 +75,11 @@ def new_harvester(**kwargs) -> Harvester: from .anticaptcha import Anticaptcha from .capmonster import Capmonster from .capsolver import Capsolver + from .captchaai import CaptchaAI - site = kwargs.get("solving_site","").lower() + site = kwargs.get("solving_site","") + if isinstance(site, str): + site = site.lower() if site == 1 or site == "capmonster": return Capmonster(**kwargs) elif site == 2 or site == "anticaptcha": @@ -82,9 +88,12 @@ def new_harvester(**kwargs) -> Harvester: return Twocap(**kwargs) elif site == 4 or site == "capsolver": return Capsolver(**kwargs) + elif site == 5 or site == "captchaai": + return CaptchaAI(**kwargs) raise captchaExceptions.NoHarvesterException("No solving site selected") # Just for backward compatibility def captcha_harvesters(**kwargs) -> Harvester: + warn('This function is deprecated. Use the `new_harvester()` function', DeprecationWarning, stacklevel=2) return new_harvester(**kwargs) \ No newline at end of file diff --git a/captchatools/anticaptcha.py b/captchatools/anticaptcha.py index cdfa1c5..cc1a473 100644 --- a/captchatools/anticaptcha.py +++ b/captchatools/anticaptcha.py @@ -1,5 +1,5 @@ from . import Harvester -from . import exceptions as captchaExceptions +from .errors import ErrCodeToException import requests from typing import Optional import time @@ -13,7 +13,7 @@ def get_balance(self) -> float: try: resp = requests.post("https://api.anti-captcha.com/getBalance", json=payload ,timeout=20).json() if resp["errorId"] == 1: # Means there was an error - self.check_error(resp["errorCode"]) + ErrCodeToException("Anticaptcha", resp["errorCode"]) return float(resp["balance"]) except requests.RequestException: pass @@ -86,7 +86,7 @@ def __get_id(self,**kwargs): try: resp = requests.post(BASEURL + "/createTask " , json=payload, timeout=20).json() if resp["errorId"] != 0: # Means there was an error: - self.check_error(resp["errorCode"]) + ErrCodeToException("Anticaptcha", resp["errorCode"]) return resp["taskId"] except (requests.RequestException, KeyError): pass @@ -97,7 +97,7 @@ def __get_answer(self,task_id:int): try: response = requests.post(BASEURL + "/getTaskResult",json=payload,timeout=20,).json() if response["errorId"] != 0: # Means there was an error - self.check_error(response["errorId"]) + ErrCodeToException("Anticaptcha", response["errorId"]) if response["status"] == "processing": time.sleep(3) continue @@ -106,26 +106,4 @@ def __get_answer(self,task_id:int): else: return response["solution"]["gRecaptchaResponse"] except (requests.RequestException, KeyError): - pass - - @staticmethod - def check_error(error_code): - if error_code == "ERROR_ZERO_BALANCE": - raise captchaExceptions.NoBalanceException() - elif error_code == "ERROR_WRONG_GOOGLEKEY": - raise captchaExceptions.WrongSitekeyException() - elif error_code == "ERROR_WRONG_USER_KEY" or error_code == "ERROR_KEY_DOES_NOT_EXIST": - raise captchaExceptions.WrongAPIKeyException() - elif error_code == "ERROR_TOO_BIG_CAPTCHA_FILESIZE": - raise captchaExceptions.CaptchaIMGTooBig() - elif error_code == "ERROR_PAGEURL": - raise captchaExceptions.TaskDetails(f"Error: {error_code}") - elif error_code == "MAX_USER_TURN" or error_code == "ERROR_NO_SLOT_AVAILABLE": - raise captchaExceptions.NoSlotAvailable("No slot available") - elif error_code == "ERROR_IP_NOT_ALLOWED" or error_code == "IP_BANNED" or error_code == "ERROR_IP_BLOCKED": - return captchaExceptions.Banned(error_code) - elif error_code == "ERROR_ZERO_CAPTCHA_FILESIZE" or error_code == "ERROR_UPLOAD" or \ - error_code == "ERROR_CAPTCHAIMAGE_BLOCKED" or error_code == "ERROR_IMAGE_TYPE_NOT_SUPPORTED" or \ - error_code == "ERROR_WRONG_FILE_EXTENSION": - raise captchaExceptions.CaptchaImageError(error_code) - else: raise captchaExceptions.UnknownError(f"Error returned from 2captcha: {error_code}") + pass \ No newline at end of file diff --git a/captchatools/capmonster.py b/captchatools/capmonster.py index eed930f..bedafd5 100644 --- a/captchatools/capmonster.py +++ b/captchatools/capmonster.py @@ -1,4 +1,4 @@ -from . import exceptions as captchaExceptions +from .errors import ErrCodeToException from . import Harvester import time import requests @@ -18,7 +18,7 @@ def get_balance(self) -> float: try: resp = requests.post(BASEURL + "/getBalance", json=payload ,timeout=20).json() if resp["errorId"] == 1: # Means there was an error - self.check_error(resp["errorCode"]) + ErrCodeToException("Capmonster", resp["errorCode"]) return float(resp["balance"]) except requests.RequestException: pass @@ -91,7 +91,7 @@ def __get_id(self,**kwargs): try: resp = requests.post(BASEURL + "/createTask" , json=payload, timeout=20).json() if resp["errorId"] != 0: # Means there was an error: - self.check_error(resp["errorCode"]) + ErrCodeToException("Capmonster", resp["errorCode"]) return resp["taskId"] except (requests.RequestException, KeyError): pass @@ -102,7 +102,7 @@ def __get_answer(self,task_id:int): try: response = requests.post(BASEURL + "/getTaskResult",json=payload,timeout=20,).json() if response["errorId"] != 0: # Means there was an error - self.check_error(response["errorCode"]) + ErrCodeToException("Capmonster", response["errorCode"]) if response["status"] == "processing": time.sleep(3) continue @@ -111,26 +111,4 @@ def __get_answer(self,task_id:int): else: return response["solution"]["gRecaptchaResponse"] except (requests.RequestException, KeyError): - pass - - @staticmethod - def check_error(error_code): - if error_code == "ERROR_ZERO_BALANCE": - raise captchaExceptions.NoBalanceException() - elif error_code == "ERROR_WRONG_GOOGLEKEY": - raise captchaExceptions.WrongSitekeyException() - elif error_code == "ERROR_WRONG_USER_KEY" or error_code == "ERROR_KEY_DOES_NOT_EXIST": - raise captchaExceptions.WrongAPIKeyException() - elif error_code == "ERROR_TOO_BIG_CAPTCHA_FILESIZE": - raise captchaExceptions.CaptchaIMGTooBig() - elif error_code == "ERROR_PAGEURL": - raise captchaExceptions.TaskDetails(f"Error: {error_code}") - elif error_code == "MAX_USER_TURN" or error_code == "ERROR_NO_SLOT_AVAILABLE": - raise captchaExceptions.NoSlotAvailable("No slot available") - elif error_code == "ERROR_IP_NOT_ALLOWED" or error_code == "IP_BANNED" or error_code == "ERROR_IP_BLOCKED": - return captchaExceptions.Banned(error_code) - elif error_code == "ERROR_ZERO_CAPTCHA_FILESIZE" or error_code == "ERROR_UPLOAD" or \ - error_code == "ERROR_CAPTCHAIMAGE_BLOCKED" or error_code == "ERROR_IMAGE_TYPE_NOT_SUPPORTED" or \ - error_code == "ERROR_WRONG_FILE_EXTENSION": - raise captchaExceptions.CaptchaImageError(error_code) - else: raise captchaExceptions.UnknownError(f"Error returned from anticaptcha: {error_code}") \ No newline at end of file + pass \ No newline at end of file diff --git a/captchatools/capsolver.py b/captchatools/capsolver.py index 43d1bda..622bb6c 100644 --- a/captchatools/capsolver.py +++ b/captchatools/capsolver.py @@ -1,4 +1,4 @@ -from . import exceptions as captchaExceptions +from .errors import ErrCodeToException from . import Harvester import time import requests @@ -18,7 +18,7 @@ def get_balance(self) -> float: try: resp = requests.post(BASEURL + "/getBalance", json=payload ,timeout=20).json() if resp["errorId"] == 1: # Means there was an error - self.check_error(resp["errorCode"]) + ErrCodeToException("Capsolver", resp["errorCode"]) return float(resp["balance"]) except requests.RequestException: pass @@ -103,7 +103,7 @@ def __get_id(self,**kwargs): try: resp = requests.post(BASEURL + "/createTask" , json=payload, timeout=20).json() if resp["errorId"] != 0: # Means there was an error: - self.check_error(resp["errorCode"]) + ErrCodeToException("Capsolver", resp["errorCode"]) # Check if there is an answer already available if resp["status"] == "ready": @@ -122,7 +122,7 @@ def __get_answer(self,task_id:int): try: response = requests.post(BASEURL + "/getTaskResult",json=payload,timeout=20,).json() if response["errorId"] != 0: # Means there was an error - self.check_error(response["errorDescription"]) + ErrCodeToException("Capsolver", response["errorDescription"]) if response["status"] == "processing": time.sleep(3) continue @@ -131,26 +131,4 @@ def __get_answer(self,task_id:int): else: return response["solution"]["gRecaptchaResponse"] except (requests.RequestException, KeyError): - pass - - @staticmethod - def check_error(error_code): - if error_code == "ERROR_ZERO_BALANCE": - raise captchaExceptions.NoBalanceException() - elif error_code == "ERROR_WRONG_GOOGLEKEY": - raise captchaExceptions.WrongSitekeyException() - elif error_code == "ERROR_WRONG_USER_KEY" or error_code == "ERROR_KEY_DOES_NOT_EXIST": - raise captchaExceptions.WrongAPIKeyException() - elif error_code == "ERROR_TOO_BIG_CAPTCHA_FILESIZE": - raise captchaExceptions.CaptchaIMGTooBig() - elif error_code == "ERROR_REQUIRED_FIELDS": - raise captchaExceptions.TaskDetails(f"Error: {error_code}") - elif error_code == "ERROR_SERVICE_UNAVALIABLE" or error_code == "ERROR_THREADS_MAXIMUM": - raise captchaExceptions.NoSlotAvailable("No slot available") - elif error_code == "ERROR_IP_NOT_ALLOWED" or error_code == "IP_BANNED" or error_code == "ERROR_IP_BLOCKED": - return captchaExceptions.Banned(error_code) - elif error_code == "ERROR_ZERO_CAPTCHA_FILESIZE" or error_code == "ERROR_UPLOAD" or \ - error_code == "ERROR_CAPTCHAIMAGE_BLOCKED" or error_code == "ERROR_IMAGE_TYPE_NOT_SUPPORTED" or \ - error_code == "ERROR_WRONG_FILE_EXTENSION": - raise captchaExceptions.CaptchaImageError(error_code) - else: raise captchaExceptions.UnknownError(f"Error returned from Capsovler: {error_code}") \ No newline at end of file + pass \ No newline at end of file diff --git a/captchatools/captchaai.py b/captchatools/captchaai.py new file mode 100644 index 0000000..96ba835 --- /dev/null +++ b/captchatools/captchaai.py @@ -0,0 +1,96 @@ +from . import Harvester +import requests +from .errors import ErrCodeToException +from typing import Optional +import time + +BASEURL = "https://ocr.captchaai.com/in.php" + +class CaptchaAI(Harvester): + def get_balance(self) -> float: + url = f"https://ocr.captchaai.com/res.php?key={self.api_key}&action=getbalance&json=1" + for _ in range(5): + try: + resp = requests.get(url, timeout=20).json() + if resp["status"] == 0: # Means there was an error + ErrCodeToException("CaptchaAI",resp["request"]) + return float(resp["request"]) + except requests.RequestException: + pass + + def get_token(self, b64_img: Optional[str] = None, user_agent: Optional[str] = None, proxy: Optional[str] = None, proxy_type: Optional[str] = None): + # Get ID + task_id = self.__get_id( + b64_img=b64_img, + user_agent=user_agent, + proxy=proxy, + proxy_type=proxy_type + ) + + # Get Answer + return self.__get_answer(task_id) + + def __create_uri_parms(self, **kwargs): + '''Creats the URI params to be used for submitting captcha info''' + params = { + "key": self.api_key, + "json": 1, + "pageurl": self.captcha_url, + } + if self.captcha_type == "image" or self.captcha_type == "normal": + params["method"] = "base64" + params["body"] = kwargs.get("b64_img", "") + elif self.captcha_type == "v2": + params["method"] = "userrecaptcha" + params["googlekey"] = self.sitekey + if self.invisible_captcha: + params["invisible"] = 1 + elif self.captcha_type == "v3": + params["method"] = "userrecaptcha" + params["version"] = "v3" + params["googlekey"] = self.sitekey + params["pageurl"] = self.captcha_url + if self.action != "": + params["action"] = self.action + if self.min_score is not None: + params["min_score"] = self.min_score + elif self.captcha_type == "hcap" or self.captcha_type == "hcaptcha": + params["method"] = "hcaptcha" + params["sitekey"] = self.sitekey + + # Add Global Data + if kwargs.get("proxy", None) is not None: + params["proxy"] = kwargs.get("proxy") + pxy_type = kwargs.get("proxy_type", "http") + params["proxytype"] = pxy_type + if kwargs.get("user_agent", None) is not None: + params["userAgent"] = kwargs.get("user_agent") + return params + + def __get_id(self,**kwargs): + # Create Payload + params = self.__create_uri_parms(**kwargs) + + # Get token & return it + for _ in range(50): + try: + resp = requests.get(BASEURL, params=params ,timeout=20).json() + if resp["status"] == 0: # Means there was an error: + ErrCodeToException("CaptchaAI",resp["request"]) + return resp["request"] + except (requests.RequestException, KeyError): + pass + + def __get_answer(self,task_id:int): + for _ in range(100): + try: + response = requests.get(f"https://ocr.captchaai.com/res.php?key={self.api_key}&action=get&id={task_id}&json=1",timeout=20,).json() + if response["status"] == 0 and response["request"] != "CAPCHA_NOT_READY": # Error checking + ErrCodeToException("CaptchaAI",response["request"]) + if response["status"] == 0 and response["request"] == "CAPCHA_NOT_READY": + time.sleep(4) + continue + return response["request"] # Return the captcha token + except (requests.RequestException, KeyError): + pass + \ No newline at end of file diff --git a/captchatools/errors.py b/captchatools/errors.py new file mode 100644 index 0000000..d490d98 --- /dev/null +++ b/captchatools/errors.py @@ -0,0 +1,25 @@ +from . import exceptions as captchaExceptions + +def ErrCodeToException(site: str, error_code:str): + ''' + Converts a given error code from the solving site and raises an appropriate exception + ''' + if error_code == "ERROR_ZERO_BALANCE": + raise captchaExceptions.NoBalanceException() + elif error_code == "ERROR_WRONG_GOOGLEKEY": + raise captchaExceptions.WrongSitekeyException() + elif error_code == "ERROR_WRONG_USER_KEY" or error_code == "ERROR_KEY_DOES_NOT_EXIST": + raise captchaExceptions.WrongAPIKeyException() + elif error_code == "ERROR_TOO_BIG_CAPTCHA_FILESIZE": + raise captchaExceptions.CaptchaIMGTooBig() + elif error_code == "ERROR_PAGEURL": + raise captchaExceptions.TaskDetails(f"Error: {error_code}") + elif error_code == "MAX_USER_TURN" or error_code == "ERROR_NO_SLOT_AVAILABLE": + raise captchaExceptions.NoSlotAvailable("No slot available") + elif error_code == "ERROR_IP_NOT_ALLOWED" or error_code == "IP_BANNED": + return captchaExceptions.Banned(error_code) + elif error_code == "ERROR_ZERO_CAPTCHA_FILESIZE" or error_code == "ERROR_UPLOAD" or \ + error_code == "ERROR_CAPTCHAIMAGE_BLOCKED" or error_code == "ERROR_IMAGE_TYPE_NOT_SUPPORTED" or \ + error_code == "ERROR_WRONG_FILE_EXTENSION": + raise captchaExceptions.CaptchaImageError(error_code) + else: raise captchaExceptions.UnknownError(f"Error returned from {site}: {error_code}") \ No newline at end of file diff --git a/captchatools/exceptions.py b/captchatools/exceptions.py index 545c329..613fab4 100644 --- a/captchatools/exceptions.py +++ b/captchatools/exceptions.py @@ -1,70 +1,88 @@ -class WrongAPIKeyException(Exception): +# ------------------------------------------------------------------------------- # + +class HarvesterException(Exception): + ''' + This exception is the base exception for all things related to the harvester + ''' + +class NoHarvesterException(HarvesterException): + ''' + This exception gets thrown when a user doesn't properly set a harvester. + ''' + def __init__(self, message): + super().__init__(message) + +class NoCaptchaType(HarvesterException): + ''' + This exception gets thrown when no captcha type was set + ''' + def __init__(self, message): + super().__init__(message) + +class WrongAPIKeyException(HarvesterException): ''' This exception gets thrown when the user provides a wrong API Key ''' def __init__(self, message="[captchatools] Incorrect API key for the captcha solving site"): - super(WrongAPIKeyException, self).__init__(message) - + super().__init__(message) -class NoBalanceException(Exception): +class TaskDetails(HarvesterException): + ''' + This exceptions gets thrown when there is missing data + ''' + +class Banned(HarvesterException): + ''' + This exception gets thrown when the user is banned from the solving site + ''' + + +class NoBalanceException(HarvesterException): ''' This exception gets thrown when there is no more funds available for the provider ''' def __init__(self, message="[captchatools] No balance available"): - super(NoBalanceException, self).__init__(message) + super().__init__(message) - -class WrongSitekeyException(Exception): +class WrongSitekeyException(HarvesterException): ''' This exception gets thrown when the user provides a wrong google sitekey ''' def __init__(self, message="[captchatools] Incorrect google sitekey"): - super(WrongSitekeyException, self).__init__(message) + super().__init__(message) +# ------------------------------------------------------------------------------- # -class NoHarvesterException(Exception): +class CaptchaAnswerException(Exception): ''' - This exception gets thrown when a user doesn't properly set a harvester. + Base exception for errors related to captcha answers ''' -class CaptchaIMGTooBig(Exception): +class CaptchaIMGTooBig(CaptchaAnswerException): ''' This exception gets thrown when the filesize of the captcha image is too big for the solving site. ''' def __init__(self, message="[captchatools] Size of the captcha image is too big."): - super(CaptchaIMGTooBig, self).__init__(message) + super().__init__(message) -class FailedToGetCapIMG(Exception): +class FailedToGetCapIMG(CaptchaAnswerException): ''' This exception gets thrown when the program fails to get the captcha image after 3 tries ''' def __init__(self, message="[captchatools] Failed to fetch captcha image."): - super(FailedToGetCapIMG, self).__init__(message) - -class Banned(Exception): - ''' - This exception gets thrown when the user is banned from the solving site - ''' + super().__init__(message) -class TaskDetails(Exception): - ''' - This exceptions gets thrown when there is missing data - ''' - -class NoSlotAvailable(Exception): +class NoSlotAvailable(CaptchaAnswerException): ''' This exceptions gets thrown when there is no worker available ''' -class CaptchaImageError(Exception): +class CaptchaImageError(CaptchaAnswerException): ''' This exception gets thrown when there is an error with the captcha image ''' +# ------------------------------------------------------------------------------- # + class UnknownError(Exception): ''' This exceptions gets thrown when there is an unknown error ''' - -class NoCaptchaType(Exception): - ''' - This exception gets thrown when no captcha type was set - ''' \ No newline at end of file diff --git a/captchatools/twocap.py b/captchatools/twocap.py index 2df89f7..311cbd7 100644 --- a/captchatools/twocap.py +++ b/captchatools/twocap.py @@ -1,6 +1,6 @@ from . import Harvester import requests -from . import exceptions as captchaExceptions +from .errors import ErrCodeToException from typing import Optional import time @@ -13,7 +13,7 @@ def get_balance(self) -> float: try: resp = requests.get(url, timeout=20).json() if resp["status"] == 0: # Means there was an error - self.check_error(resp["request"]) + ErrCodeToException("2Captcha",resp["request"]) return float(resp["request"]) except requests.RequestException: pass @@ -76,7 +76,7 @@ def __get_id(self,**kwargs): try: resp = requests.post(BASEURL_IN, json=payload, timeout=20).json() if resp["status"] == 0: # Means there was an error: - self.check_error(resp["request"]) + ErrCodeToException("2Captcha",resp["request"]) return resp["request"] except (requests.RequestException, KeyError): pass @@ -86,32 +86,10 @@ def __get_answer(self,task_id:int): try: response = requests.get(f"http://2captcha.com/res.php?key={self.api_key}&action=get&id={task_id}&json=1",timeout=20,).json() if response["status"] == 0 and response["request"] != "CAPCHA_NOT_READY": # Error checking - self.check_error(response["request"]) + ErrCodeToException("2Captcha",response["request"]) if response["status"] == 0 and response["request"] == "CAPCHA_NOT_READY": time.sleep(4) continue return response["request"] # Return the captcha token except (requests.RequestException, KeyError): - pass - - @staticmethod - def check_error(error_code): - if error_code == "ERROR_ZERO_BALANCE": - raise captchaExceptions.NoBalanceException() - elif error_code == "ERROR_WRONG_GOOGLEKEY": - raise captchaExceptions.WrongSitekeyException() - elif error_code == "ERROR_WRONG_USER_KEY" or error_code == "ERROR_KEY_DOES_NOT_EXIST": - raise captchaExceptions.WrongAPIKeyException() - elif error_code == "ERROR_TOO_BIG_CAPTCHA_FILESIZE": - raise captchaExceptions.CaptchaIMGTooBig() - elif error_code == "ERROR_PAGEURL": - raise captchaExceptions.TaskDetails(f"Error: {error_code}") - elif error_code == "MAX_USER_TURN" or error_code == "ERROR_NO_SLOT_AVAILABLE": - raise captchaExceptions.NoSlotAvailable("No slot available") - elif error_code == "ERROR_IP_NOT_ALLOWED" or error_code == "IP_BANNED": - return captchaExceptions.Banned(error_code) - elif error_code == "ERROR_ZERO_CAPTCHA_FILESIZE" or error_code == "ERROR_UPLOAD" or \ - error_code == "ERROR_CAPTCHAIMAGE_BLOCKED" or error_code == "ERROR_IMAGE_TYPE_NOT_SUPPORTED" or \ - error_code == "ERROR_WRONG_FILE_EXTENSION": - raise captchaExceptions.CaptchaImageError(error_code) - else: raise captchaExceptions.UnknownError(f"Error returned from 2captcha: {error_code}") \ No newline at end of file + pass \ No newline at end of file diff --git a/setup.py b/setup.py index 29785d0..ef6dadd 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from io import open PACKAGE_NAME = "captchatools" -VERSION = "1.3.0" +VERSION = "1.4.1" SHORT_DESCRIPTION = "Python module to help solve captchas with Capmonster, 2captcha and Anticaptcha API's!" GITHUB_URL = "https://github.com/Matthew17-21/Captcha-Tools"