diff --git a/README.md b/README.md index ac1f6e4..bd704ce 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Examples of API requests for different captcha types are available on the [Pytho - [Prosopo](#prosopo) - [Temu](#temu) - [CyberSiARA](#cybersiara) + - [Altcha Captcha](#altcha-Captcha) - [Other methods](#other-methods) - [send / get\_result](#send--get_result) - [balance](#balance) @@ -524,6 +525,17 @@ result = solver.cybersiara(master_url_id='tpjOCKjjpdzv3d8Ub2E9COEWKt1vl1Mv', param1=..., ...) ``` +### Altcha Captcha + +[API method description.](http://2captcha.com/2captcha-api#altchacaptcha) + +Use this method to solve Altcha Captcha. Returns a token. +```python +result = solver.altcha(pageurl='https://mysite.com/page/with/altcha', + challenge_json='{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + # or: challenge_url='https://example.com/altcha-challenge',) +``` + ## Other methods ### send / get_result diff --git a/examples/async/async_altcha.py b/examples/async/async_altcha.py new file mode 100644 index 0000000..dcdd98e --- /dev/null +++ b/examples/async/async_altcha.py @@ -0,0 +1,31 @@ +import asyncio +import os +import sys + +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) + +from twocaptcha import AsyncTwoCaptcha + +# in this example we store the API key inside environment variables that can be set like: +# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS +# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows +# you can just set the API key directly to it's value like: +# api_key="1abc234de56fab7c89012d34e56fa7b8" + +api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY') + +solver = AsyncTwoCaptcha(api_key) + +async def solve_captcha(): + try: + return await solver.altcha( + pageurl='https://mysite.com/page/with/altcha', + challenge_json='{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + # challenge_url='https://example/altcha', + ) + except Exception as e: + sys.exit(e) + +if __name__ == '__main__': + result = asyncio.run(solve_captcha()) + sys.exit('result: ' + str(result)) \ No newline at end of file diff --git a/examples/async/async_altcha_options.py b/examples/async/async_altcha_options.py new file mode 100644 index 0000000..9e70ffd --- /dev/null +++ b/examples/async/async_altcha_options.py @@ -0,0 +1,40 @@ +import asyncio +import os +import sys + +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) + +from twocaptcha import AsyncTwoCaptcha + +# in this example we store the API key inside environment variables that can be set like: +# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS +# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows +# you can just set the API key directly to it's value like: +# api_key="1abc234de56fab7c89012d34e56fa7b8" + +api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY') + +config = { + 'server': '2captcha.com', # can be also set to 'rucaptcha.com' + 'apiKey': api_key, + 'softId': 123, + 'defaultTimeout': 120, + 'recaptchaTimeout': 600, + 'pollingInterval': 10, + } + +solver = AsyncTwoCaptcha(api_key) + +async def solve_captcha(): + try: + return await solver.altcha( + pageurl='https://mysite.com/page/with/altcha', + challenge_json='{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + # challenge_url='https://example/altcha', + ) + except Exception as e: + sys.exit(e) + +if __name__ == '__main__': + result = asyncio.run(solve_captcha()) + sys.exit('result: ' + str(result)) \ No newline at end of file diff --git a/examples/sync/altcha.py b/examples/sync/altcha.py new file mode 100644 index 0000000..c86edf8 --- /dev/null +++ b/examples/sync/altcha.py @@ -0,0 +1,28 @@ +import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) + +from twocaptcha import TwoCaptcha + +# in this example we store the API key inside environment variables that can be set like: +# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS +# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows +# you can just set the API key directly to it's value like: +# api_key="1abc234de56fab7c89012d34e56fa7b8" + +api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY') + +solver = TwoCaptcha(api_key) + +try: + result = solver.altcha( + pageurl='https://mysite.com/page/with/altcha', + challenge_json='{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + # challenge_url='https://example/altcha', + ) + +except Exception as e: + sys.exit(e) + +else: + sys.exit('result: ' + str(result)) \ No newline at end of file diff --git a/examples/sync/altcha_options.py b/examples/sync/altcha_options.py new file mode 100644 index 0000000..c40f0a6 --- /dev/null +++ b/examples/sync/altcha_options.py @@ -0,0 +1,37 @@ +import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) + +from twocaptcha import TwoCaptcha + +# in this example we store the API key inside environment variables that can be set like: +# export APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Linux or macOS +# set APIKEY_2CAPTCHA=1abc234de56fab7c89012d34e56fa7b8 on Windows +# you can just set the API key directly to it's value like: +# api_key="1abc234de56fab7c89012d34e56fa7b8" + +api_key = os.getenv('APIKEY_2CAPTCHA', 'YOUR_API_KEY') + +config = { + 'server': '2captcha.com', # can be also set to 'rucaptcha.com' + 'apiKey': api_key, + 'softId': 123, + 'defaultTimeout': 120, + 'recaptchaTimeout': 600, + 'pollingInterval': 10, + } + +solver = TwoCaptcha(api_key) + +try: + result = solver.altcha( + pageurl='https://mysite.com/page/with/altcha', + challenge_json='{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + # challenge_url='https://example/altcha', + ) + +except Exception as e: + sys.exit(e) + +else: + sys.exit('result: ' + str(result)) \ No newline at end of file diff --git a/tests/async/test_async_altcha.py b/tests/async/test_async_altcha.py new file mode 100644 index 0000000..6bbcef5 --- /dev/null +++ b/tests/async/test_async_altcha.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import unittest + +try: + from .abstract_async import AsyncAbstractTest +except ImportError: + from abstract_async import AsyncAbstractTest + + +class AsyncAltchaTest(AsyncAbstractTest): + def test_all_params(self): + params = { + 'pageurl': 'https://mysite.com/page/with/altcha', + 'challenge_json': '{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + } + + sends = { + 'method': 'altcha', + 'pageurl': 'https://mysite.com/page/with/altcha', + 'challenge_json': '{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + } + + self.send_return(sends, self.solver.altcha, **params) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/async/test_async_temu.py b/tests/async/test_async_temu.py index fe9ee52..0188f1e 100644 --- a/tests/async/test_async_temu.py +++ b/tests/async/test_async_temu.py @@ -25,7 +25,7 @@ def test_all_params(self): 'part3': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' } - self.send_return(sends, self.solver.lemin, **params) + self.send_return(sends, self.solver.temu, **params) if __name__ == '__main__': diff --git a/tests/sync/test_altcha.py b/tests/sync/test_altcha.py new file mode 100644 index 0000000..beb3e89 --- /dev/null +++ b/tests/sync/test_altcha.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +import unittest + +try: + from .abstract import AbstractTest +except ImportError: + from abstract import AbstractTest + + +class AltchaTest(AbstractTest): + + def test_all_params(self): + params = { + 'pageurl': 'https://mysite.com/page/with/altcha', + 'challenge_json': '{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + } + + sends = { + 'method': 'altcha', + 'pageurl': 'https://mysite.com/page/with/altcha', + 'challenge_json': '{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}', + } + + return self.send_return(sends, self.solver.altcha, **params) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/twocaptcha/async_solver.py b/twocaptcha/async_solver.py index 8a58f8a..02ee062 100644 --- a/twocaptcha/async_solver.py +++ b/twocaptcha/async_solver.py @@ -998,6 +998,41 @@ async def yandex_smart(self, sitekey, url, **kwargs): **kwargs) return result + async def altcha(self, pageurl, challenge_url=None, challenge_json=None, **kwargs): + '''Wrapper for solving Altcha Captcha. + + Parameters + __________ + pageurl : str + Full URL of the page where you solve the captcha. + challenge_url : str + The value of the 'challenge_url' parameter for the 'altcha-widget' element containing the captcha on the page. + You can send either challenge_url or challenge_json parameter, but not two of it simultaneously. + challenge_json : str + The contents of the file from the 'challenge_url' parameter. You can send either challenge_url or challenge_json + parameter, but not two of it simultaneously. + proxy : dict, optional + {'type': 'HTTPS', 'uri': 'login:password@IP_address:PORT'}. + + ''' + + if (challenge_url is None) == (challenge_json is None): + raise ValidationException( + 'You must provide exactly one of challenge_url or challenge_json' + ) + + params = { + 'pageurl': pageurl, + 'method': 'altcha', + **kwargs,} + + if challenge_url is not None: + params['challenge_url'] = challenge_url + if challenge_json is not None: + params['challenge_json'] = challenge_json + + return await self.solve(**params) + async def solve(self, timeout=0, polling_interval=0, **kwargs): '''Sends captcha, receives result. diff --git a/twocaptcha/solver.py b/twocaptcha/solver.py index 2ff945b..6a32c56 100755 --- a/twocaptcha/solver.py +++ b/twocaptcha/solver.py @@ -105,6 +105,10 @@ class TwoCaptcha(): Use this method to solve DataDome captcha. cybersiara(master_url_id, pageurl, userAgent, **kwargs) Use this method to solve CyberSiARA. Returns a token. + yandex_smart(self, sitekey, url, **kwargs) + Wrapper for solving Yandex Smart. + altcha(self, pageurl, challenge_url=None, challenge_json=None, **kwargs) + Wrapper for solving Altcha Captcha. solve(timeout=0, polling_interval=0, **kwargs) Sends CAPTCHA data and retrieves the result. balance() @@ -1128,6 +1132,41 @@ def yandex_smart(self, sitekey, url, **kwargs): **kwargs) return result + def altcha(self, pageurl, challenge_url=None, challenge_json=None, **kwargs): + '''Wrapper for solving Altcha Captcha. + + Parameters + __________ + pageurl : str + Full URL of the page where you solve the captcha. + challenge_url : str + The value of the 'challenge_url' parameter for the 'altcha-widget' element containing the captcha on the page. + You can send either challenge_url or challenge_json parameter, but not two of it simultaneously. + challenge_json : str + The contents of the file from the 'challenge_url' parameter. You can send either challenge_url or challenge_json + parameter, but not two of it simultaneously. + proxy : dict, optional + {'type': 'HTTPS', 'uri': 'login:password@IP_address:PORT'}. + + ''' + + if (challenge_url is None) == (challenge_json is None): + raise ValidationException( + 'You must provide exactly one of challenge_url or challenge_json' + ) + params = { + 'pageurl': pageurl, + 'method': "altcha", + **kwargs, + } + if challenge_url is not None: + params['challenge_url'] = challenge_url + if challenge_json is not None: + params['challenge_json'] = challenge_json + + return self.solve(**params) + + def solve(self, timeout=0, polling_interval=0, **kwargs): '''Sends captcha, receives result.