feature!: добавлен механизм обхода антибот защиты
This commit is contained in:
1 parent
f5871710ab
commit
1d2fdeae70
17 files changed
+735
-16
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import logging
|
||||
|
||||
from playwright.async_api import Page
|
||||
|
||||
from ..base import Detector, ChallengeInfo, Solver, AntiBotProvider
|
||||
from ..base import Stage
|
||||
from ..registry import register
|
||||
from ..exceptions import IframeLoadError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(logging.DEBUG)
|
||||
log.addHandler(logging.StreamHandler())
|
||||
|
||||
|
||||
class ReCaptchaSolver(Solver):
|
||||
|
||||
def __init__(self, captcha_solver) -> None:
|
||||
super().__init__(captcha_solver=captcha_solver)
|
||||
self.captcha_solver = self._opt["captcha_solver"]
|
||||
|
||||
async def solve(self, page: Page, info: ChallengeInfo):
|
||||
if info.stage == Stage.INTERSTITIAL:
|
||||
await page.wait_for_timeout(15)
|
||||
elif info.stage == Stage.CHECKBOX:
|
||||
checkbox_selector = "#recaptcha-anchor"
|
||||
element = page.locator(checkbox_selector)
|
||||
async with page.expect_response("**/recaptcha/enterprise/reload**", timeout=30_000):
|
||||
await element.click()
|
||||
else:
|
||||
element = page.locator("body > div:nth-child(2) > div:nth-child(1)")
|
||||
if await element.is_visible():
|
||||
await element.click()
|
||||
|
||||
self.captcha_solver.recaptcha(page)
|
||||
# TODO: execute js
|
||||
|
||||
class ReCaptchaDetector(Detector):
|
||||
|
||||
async def detect(self, page: Page, info: ChallengeInfo):
|
||||
info.meta = {}
|
||||
checkbox_selector = "#recaptcha-anchor"
|
||||
interactive_marker_selector = "body > div:nth-child(2) > div:nth-child(4) > iframe:nth-child(1)"
|
||||
|
||||
# попытка определить что мы вообще на странице блокировки
|
||||
marker_selector = "#captcha-form"
|
||||
if not await page.query_selector(marker_selector):
|
||||
log.debug("Page is not a challenge form")
|
||||
if info.success_locator:
|
||||
info.success = bool(await page.query_selector(info.success_locator))
|
||||
info.meta["reason"] = [
|
||||
"Success locator not present and marker too.",
|
||||
"Marker not present but success locator is it!"
|
||||
][info.success]
|
||||
else:
|
||||
info.success = True
|
||||
# noinspection unresolved-references
|
||||
info.meta["reason"] = "Page is not a challenge form"
|
||||
return
|
||||
|
||||
# ожидаем когда будет загружен чекбокс
|
||||
if not await page.wait_for_selector(checkbox_selector, timeout=30_000):
|
||||
log.debug("Checkbox not present")
|
||||
# noinspection unresolved-references
|
||||
info.meta["reason"] = "Checkbox not present"
|
||||
raise IframeLoadError("Checkbox not present")
|
||||
else:
|
||||
# нужно сделать клик
|
||||
info.stage = Stage.CHECKBOX
|
||||
|
||||
if await page.wait_for_selector(interactive_marker_selector, timeout=15_000):
|
||||
# нужно решение
|
||||
info.stage = Stage.INTERACTIVE
|
||||
|
||||
return
|
||||
|
||||
|
||||
@register
|
||||
class ReCaptchaProvider(AntiBotProvider):
|
||||
provider = 'recaptcha'
|
||||
_solver_cls = ReCaptchaSolver
|
||||
_detector_cls = ReCaptchaDetector
|
||||
Reference in new issue
Block a user