Skip to content

Async Solver #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

 
Expand Down Expand Up @@ -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).

 
Expand Down
4 changes: 2 additions & 2 deletions pypasser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .reCaptchaV3 import reCaptchaV3
from .reCaptchaV2 import reCaptchaV2
from .reCaptchaV3 import reCaptchaV3, AsyncReCaptchaV3
from .reCaptchaV2 import reCaptchaV2
70 changes: 68 additions & 2 deletions pypasser/reCaptchaV3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -85,4 +86,69 @@ def get_recaptcha_response(endpoint: str, params: str, data: str) -> str:
if not results:
raise RecaptchaResponseNotFound()

return results[0]
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]