@@ -599,6 +599,85 @@ def serialize(self, **result: Any) -> dict[str, Any]:
599599 return data
600600
601601
602+ class TurnstileTaskProxyless (BaseTask ):
603+ """Solve a Cloudflare Turnstile challenge without a proxy.
604+
605+ Turnstile is Cloudflare's CAPTCHA replacement used on millions of websites.
606+ The service automatically detects all Turnstile subtypes (manual,
607+ non-interactive, invisible).
608+
609+ After the job completes, retrieve the token with
610+ :meth:`Job.get_token_response`.
611+
612+ :param website_url: Full URL of the page where the Turnstile widget appears.
613+ :param website_key: The Turnstile ``sitekey`` from the page source.
614+ :param action: Optional action parameter passed to the Turnstile widget.
615+ :param cdata: Optional ``cData`` token for Cloudflare-protected pages.
616+ :param chl_page_data: Optional ``chlPageData`` token for Cloudflare pages.
617+
618+ Example::
619+
620+ task = TurnstileTaskProxyless(
621+ website_url="https://example.com",
622+ website_key="0x4AAAAAAABS7vwvV6VFfMcD",
623+ )
624+ """
625+
626+ type = "TurnstileTaskProxyless"
627+ websiteURL = None
628+ websiteKey = None
629+
630+ def __init__ (
631+ self ,
632+ website_url : str ,
633+ website_key : str ,
634+ action : str | None = None ,
635+ cdata : str | None = None ,
636+ chl_page_data : str | None = None ,
637+ * args : Any ,
638+ ** kwargs : Any ,
639+ ) -> None :
640+ self .websiteURL = website_url
641+ self .websiteKey = website_key
642+ self .action = action
643+ self .cData = cdata
644+ self .chlPageData = chl_page_data
645+ super ().__init__ (* args , ** kwargs )
646+
647+ def serialize (self , ** result : Any ) -> dict [str , Any ]:
648+ data = super ().serialize (** result )
649+ data ["websiteURL" ] = self .websiteURL
650+ data ["websiteKey" ] = self .websiteKey
651+ if self .action is not None :
652+ data ["action" ] = self .action
653+ if self .cData is not None :
654+ data ["cData" ] = self .cData
655+ if self .chlPageData is not None :
656+ data ["chlPageData" ] = self .chlPageData
657+ return data
658+
659+
660+ class TurnstileTask (ProxyMixin , UserAgentMixin , CookieMixin , TurnstileTaskProxyless ):
661+ """Solve a Cloudflare Turnstile challenge through a proxy.
662+
663+ Same as :class:`TurnstileTaskProxyless` but additionally requires
664+ proxy, user-agent, and optional cookie parameters.
665+
666+ Note that the proxy-based approach is slower and requires high-quality,
667+ self-hosted proxies.
668+
669+ :param user_agent: Browser User-Agent string.
670+ :param cookies: Optional cookie string (default: ``""``).
671+ :param proxy_type: Proxy protocol (``"http"``, ``"socks4"``, ``"socks5"``).
672+ :param proxy_address: Proxy server hostname or IP.
673+ :param proxy_port: Proxy server port.
674+ :param proxy_login: Proxy username (empty string if none).
675+ :param proxy_password: Proxy password (empty string if none).
676+ """
677+
678+ type = "TurnstileTask"
679+
680+
602681class AntiGateTask (ProxyMixin , AntiGateTaskProxyless ):
603682 """Solve a custom AntiGate task through a proxy.
604683
0 commit comments