chore: настройка определения что мы на странице cf_turnstile
This commit is contained in:
1 parent
257310b7d5
commit
405e5ed2d0
1 file changed
+55
-4
@@ -84,7 +84,7 @@ class CloudflareDetector(Detector):
|
||||
|
||||
async def detect(self, page: Page, info: ChallengeInfo):
|
||||
log.debug("CloudflareDetector run")
|
||||
await wait_for_networkidle(page)
|
||||
await wait_for_page_stability(page, True, False)
|
||||
|
||||
log.debug("Страница загружена полностью")
|
||||
info.meta = {}
|
||||
@@ -94,7 +94,9 @@ class CloudflareDetector(Detector):
|
||||
|
||||
log.debug(f"ищем {marker_selector} успех если есть {info.success_locator}")
|
||||
|
||||
if not await page.query_selector(marker_selector):
|
||||
cf_type = await self._detect_cloudflare(page)
|
||||
|
||||
if not cf_type:
|
||||
log.debug("на странице нет маркера преграды")
|
||||
if info.success_locator:
|
||||
info.success = bool(await page.query_selector(info.success_locator))
|
||||
@@ -108,8 +110,6 @@ class CloudflareDetector(Detector):
|
||||
log.debug("Решение не требуется")
|
||||
return
|
||||
|
||||
content = await page.content()
|
||||
cf_type = next((t for t in self._CTYPES if f"cType: '{t}'" in content), None)
|
||||
info.meta["cf_type"] = cf_type
|
||||
log.debug(f"cType со страницы: {cf_type!r}")
|
||||
|
||||
@@ -134,6 +134,41 @@ class CloudflareDetector(Detector):
|
||||
else:
|
||||
info.stage = Stage.INTERSTITIAL
|
||||
|
||||
@staticmethod
|
||||
async def _detect_cloudflare(page: Page) -> str | None:
|
||||
"""
|
||||
Detect the type of Cloudflare challenge present in the provided page content.
|
||||
|
||||
This function analyzes the given page content to identify whether a specific
|
||||
type of Cloudflare challenge is present. It checks for three predefined
|
||||
challenge types: non-interactive, managed, and interactive. If a challenge
|
||||
type is detected, it returns the corresponding type as a string. If no
|
||||
challenge type is detected, it returns None.
|
||||
|
||||
Args:
|
||||
page_content (str): The content of the page to analyze for Cloudflare
|
||||
challenge types.
|
||||
|
||||
Returns:
|
||||
str: A string representing the detected Cloudflare challenge type, if
|
||||
found. Returns None if no challenge matches.
|
||||
"""
|
||||
challenge_types = (
|
||||
"non-interactive",
|
||||
"managed",
|
||||
"interactive",
|
||||
)
|
||||
page_content = await page.content()
|
||||
for ctype in challenge_types:
|
||||
if f"cType: '{ctype}'" in page_content:
|
||||
return ctype
|
||||
|
||||
# Check if turnstile captcha is embedded inside the page (Usually inside a closed Shadow iframe)
|
||||
if await page.query_selector('script[src*="challenges.cloudflare.com/turnstile/v"]'):
|
||||
return "embedded"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
__CF_PATTERN__ = re.compile(r"^https://challenges\.cloudflare\.com/cdn-cgi/challenge-platform/.*")
|
||||
|
||||
@@ -170,6 +205,7 @@ class CloudflareSolver(Solver):
|
||||
while time.time() < deadline:
|
||||
if not await page.query_selector(info.detect_locator):
|
||||
return
|
||||
await page.wait_for_timeout(1)
|
||||
return
|
||||
elif info.stage == Stage.INTERSTITIAL:
|
||||
if info.success_locator:
|
||||
@@ -184,6 +220,7 @@ class CloudflareSolver(Solver):
|
||||
while time.time() < deadline:
|
||||
if not await page.query_selector(info.detect_locator):
|
||||
return
|
||||
await page.wait_for_timeout(1)
|
||||
return
|
||||
else:
|
||||
|
||||
@@ -193,6 +230,20 @@ class CloudflareSolver(Solver):
|
||||
await captcha_solver.solve(info.meta["container_selector"], page)
|
||||
# TODO: возбудить js
|
||||
|
||||
@classmethod
|
||||
def _challenge_cleared(cls, page_content: str, challenge_type: str) -> bool:
|
||||
"""
|
||||
Check whether the Cloudflare challenge is no longer present in the page content.
|
||||
|
||||
Args:
|
||||
page_content (str): The content of the page to analyze.
|
||||
challenge_type (str): The challenge type returned by `_detect_cloudflare`.
|
||||
|
||||
Returns:
|
||||
bool: True if the challenge is gone from the page, False otherwise.
|
||||
"""
|
||||
return challenge_type == "embedded" or cls._detect_cloudflare(page_content) is None
|
||||
|
||||
|
||||
@register
|
||||
class ReCaptchaProvider(AntiBotProvider):
|
||||
|
||||
Reference in new issue
Block a user