diff --git a/README.md b/README.md index ba96e86..e878894 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ pip install PyPasser --upgrade ### Install from Github (latest repo code) ``` -pip install git+https://github.com/xHossein/PyPasser@master +pip install git+https://github.com/ProtDos/PyPasser@master ```   @@ -57,6 +57,26 @@ reCaptcha_response = reCaptchaV3('ANCHOR URL') ## use this response in your request ... ``` + +  + +## Async + +  + +```python +from pypasser import AsyncReCaptchaV3 +import asyncio + +async def main(): + solver = AsyncReCaptchaV3('ANCHOR URL') + reCaptcha_response = await solver.solve() + ## use this response in your request ... + +if __name__ == "__main__": + asyncio.run(main()) +``` + Some good examples are [here](https://github.com/xHossein/PyPasser/tree/master/examples/reCaptchaV3).   diff --git a/pypasser/__init__.py b/pypasser/__init__.py index 2e84276..5660583 100644 --- a/pypasser/__init__.py +++ b/pypasser/__init__.py @@ -1,2 +1,2 @@ -from .reCaptchaV3 import reCaptchaV3 -from .reCaptchaV2 import reCaptchaV2 \ No newline at end of file +from .reCaptchaV3 import reCaptchaV3, AsyncReCaptchaV3 +from .reCaptchaV2 import reCaptchaV2 diff --git a/pypasser/reCaptchaV3/__init__.py b/pypasser/reCaptchaV3/__init__.py index 7e5fcd9..d100178 100644 --- a/pypasser/reCaptchaV3/__init__.py +++ b/pypasser/reCaptchaV3/__init__.py @@ -3,8 +3,9 @@ from pypasser.structs import Proxy from pypasser.utils import parse_url from .constants import POST_DATA, BASE_URL, BASE_HEADERS - import re +import aiohttp +import asyncio from typing import Dict, Union class reCaptchaV3: @@ -85,4 +86,69 @@ def get_recaptcha_response(endpoint: str, params: str, data: str) -> str: if not results: raise RecaptchaResponseNotFound() - return results[0] \ No newline at end of file + return results[0] + + +class AsyncReCaptchaV3: + """ + Asynchronous reCaptchaV3 bypass using aiohttp. + """ + + def __init__( + self, + anchor_url: str, + proxy: Union[Proxy, Dict] = None, + timeout: Union[int, float] = 20, + ): + self.anchor_url = anchor_url + self.proxy = proxy + self.timeout = timeout + self.prefix = "https://www.google.com/recaptcha/" + + async def solve(self) -> str: + """ + Solves the reCaptcha v3 asynchronously. + """ + data = parse_url(self.anchor_url) + + async with aiohttp.ClientSession(headers=BASE_HEADERS) as session: + # Gets recaptcha token. + token = await self.get_recaptcha_token(session, data["endpoint"], data["params"]) + + params = dict(pair.split("=") for pair in data["params"].split("&")) + + # Gets recaptcha response. + post_data = POST_DATA.format(params["v"], token, params["k"], params["co"]) + + recaptcha_response = await self.get_recaptcha_response(session, data["endpoint"], f'k={params["k"]}', + post_data) + + return recaptcha_response + + async def get_recaptcha_token(self, session: aiohttp.ClientSession, endpoint: str, params: str) -> str: + """ + Sends GET request to `anchor URL` to get recaptcha token asynchronously. + """ + async with session.get(f"{self.prefix}{endpoint}/anchor", params=params) as response: + response_text = await response.text() + + results = re.findall(r'"recaptcha-token" value="(.*?)"', response_text) + if not results: + raise RecaptchaTokenNotFound() + + return results[0] + + async def get_recaptcha_response(self, session: aiohttp.ClientSession, endpoint: str, params: str, + data: str) -> str: + """ + Sends POST request to `reload URL` to get recaptcha response asynchronously. + """ + async with session.post(f"{self.prefix}{endpoint}/reload", params=params, data=data) as response: + response_text = await response.text() + + results = re.findall(r'"rresp","(.*?)"', response_text) + if not results: + raise RecaptchaResponseNotFound() + + return results[0] +