{"id":26148,"date":"2026-09-30T04:41:16","date_gmt":"2026-09-30T04:41:16","guid":{"rendered":"https:\/\/capskip.com\/?p=26148"},"modified":"2026-09-30T04:41:16","modified_gmt":"2026-09-30T04:41:16","slug":"captchafox-python","status":"publish","type":"post","link":"https:\/\/capskip.com\/zh\/captchafox-python\/","title":{"rendered":"\u5982\u4f55\u5728 Python \u4e2d\u7528 requests \u548c httpx \u8bc6\u522b CaptchaFox"},"content":{"rendered":"<p>To solve CaptchaFox in Python, call solver.captchafox() from the capskip package with the sitekey and the page URL, put the token it returns in the cf-captcha-response form field, and send that request with the user agent that came back beside the token. The last step is where Python code usually goes wrong. requests and httpx both identify themselves in the User-Agent header by default, and a site that expects the token from the browser that minted it turns that request down, so a solve that worked perfectly can still fail on submit. CapSkip added CaptchaFox in version 1.4.0. This guide covers the key, the call, the submit, retries and running solves side by side.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">What you need<\/h2>\n<ul>\n<li>CapSkip 1.4.0 or later running on a Windows machine. That release added CaptchaFox, together with Friendly Captcha and Capy Puzzle.<\/li>\n<li>Python 3.10 or later and version 1.3.0 or later of the capskip package, the first release with a captchafox() method. The samples also use requests, and the section on parallel solves uses httpx.<\/li>\n<li>Two values from the target page: the sitekey, and the URL of the page the widget runs on. Step 1 shows where the key sits and which script tag to look at while you are there.<\/li>\n<li>An address for the solver. In Local mode CapSkip answers on 127.0.0.1 for that device only; in Server mode it listens on your network address or public IP, so a script on another machine can call it over the API. Both are set under <a href=\"https:\/\/capskip.com\/setup-guide\/#connection-settings\">connection settings<\/a>.<\/li>\n<\/ul>\n<div data-no-translation>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\"># Quoted, so cmd.exe does not read &gt;= as a redirect\npip install &quot;capskip&gt;=1.3.0&quot; requests httpx<\/pre>\n<\/div>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Step 1: read the sitekey and the widget source<\/h2>\n<p>The sitekey is public, the same for every visitor, and conventionally starts with sk_. Most pages carry it on the widget&#8217;s container, a div with the class captchafox and a data-sitekey attribute. A page that builds the widget from its own script passes the key to a captchafox.render call instead, and when neither shows up in the HTML you fetched, the key is in the Network tab: it is the path segment after \/captcha\/ in the request to api.captchafox.com.<\/p>\n<p>While you are reading the page, check which script loads the widget. Most sites load it from cdn.captchafox.com and get a plain token. Some platforms embed a package from s.uicdn.com\/mampkg\/ instead, and those sites expect a token that starts with MAM_. Solving for the wrong one still returns a token, in a format the site then refuses, so this check saves a confusing afternoon. On MAM pages the key may sit in the script&#8217;s own src, after ?key=, and the same CDN serves unrelated packages too, so match the captchafox package path rather than the host.<\/p>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">import re\n\nimport requests\n\nPAGE_URL = &quot;https:\/\/example.com\/signup&quot;\nsession = requests.Session()\nhtml = session.get(PAGE_URL, timeout=30).text\n\n# The container: &lt;div class=&quot;captchafox&quot; data-sitekey=&quot;sk_...&quot;&gt;\ntag = re.search(r'&lt;[^&gt;]*class=&quot;(?:[^&quot;]*\\s)?captchafox(?:\\s[^&quot;]*)?&quot;[^&gt;]*&gt;', html)\nkey = tag and re.search(r'data-sitekey=&quot;([^&quot;]+)&quot;', tag.group(0))\n# MAM pages may carry the key in the script src instead.\nkey = key or re.search(r'captchafox[^&quot;]*\/api\\.js\\?key=([^&quot;&amp;]+)', html)\nsitekey = key.group(1) if key else None\n\n# The MAM build expects a MAM_ token; everything else is the default.\nuses_mam = &quot;mampkg\/@mamdev\/core.frontend.libs.captchafox&quot; in html\nprint(sitekey, uses_mam)<\/pre>\n<\/div>\n<p>The class pattern is bounded by whitespace, so a wrapper element with a class such as captchafox-container does not match by accident. It expects double quotes around attribute values, which is how CaptchaFox&#8217;s own snippet writes them.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Step 2: the captchafox() call<\/h2>\n<p>To solve CaptchaFox in Python you need one method, which takes the sitekey and the page URL plus optional keyword arguments. For the standard widget, those two are all it needs.<\/p>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"># pip install &quot;capskip&gt;=1.3.0&quot;\nfrom capskip import CapSkip\n\nsolver = CapSkip(host=&quot;127.0.0.1&quot;, port=8080)\n\nresult = solver.captchafox(&quot;YOUR_SITEKEY&quot;, &quot;https:\/\/example.com\/signup&quot;)\n\nprint(result[&quot;token&quot;])           # goes in cf-captcha-response\nprint(result.get(&quot;userAgent&quot;))   # send this as the User-Agent<\/pre>\n<\/div>\n<p>The result is a plain dict. token and code hold the same string, and token is named for the field it fills. userAgent is the identity of the browser that minted the token, which is CapSkip&#8217;s own browser and not anything you sent. The key is only present when the solve reported one, so read it with result.get() and not with square brackets, or the rare solve without it raises a KeyError on the line that should have submitted the form.<\/p>\n<p>The page URL has to be the page the widget really runs on. CaptchaFox registers every key against a list of allowed domains and checks the host before it issues anything, so a key sent with the wrong page is refused every time, never intermittently. A redirect, a shortened link or a search result will not do.<\/p>\n<h3 style=\"font-size:1.3rem;line-height:1.4;\">Options the method accepts<\/h3>\n<p>For a page that loads the MAM package, pass the package path from its script tag as api_server. The SDK drops any keyword argument whose value is None before the request goes out, so you can pass the option on every call and let the Step 1 check decide it.<\/p>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"># Copied from the script tag on MAM pages.\nMAM_PACKAGE = &quot;https:\/\/s.uicdn.com\/mampkg\/@mamdev\/core.frontend.libs.captchafox\/&quot;\n\nresult = solver.captchafox(\n    sitekey,\n    PAGE_URL,\n    # None is dropped, so the standard widget sends nothing extra.\n    api_server=MAM_PACKAGE if uses_mam else None,\n)<\/pre>\n<\/div>\n<p>Besides api_server, captchafox() takes proxy, proxytype and useragent, plus a per-call timeout and polling_interval in seconds. The useragent option is accepted for compatibility with other services and deliberately not applied, because CapSkip solves in a real browser with that browser&#8217;s own consistent identity. Any other keyword, an empty sitekey or URL, a proxy dict without type and uri, or a proxy type other than HTTP, HTTPS, SOCKS5 or SOCKS5H raises a ValidationException before a request is sent.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Step 3: submit under the user agent that minted the token<\/h2>\n<p>When you solve CaptchaFox in Python, this is the step that decides whether the site accepts the token. Out of the box, requests sends a User-Agent of python-requests followed by its version number, and httpx sends python-httpx followed by its own. Neither is the browser that produced the token. Copy the returned value onto the request that carries it.<\/p>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"># session is the one Step 1 fetched the page with, so it carries its cookies.\nua = result.get(&quot;userAgent&quot;)\nresp = session.post(\n    PAGE_URL,  # or wherever the form's action attribute points\n    data={&quot;email&quot;: &quot;YOUR_EMAIL&quot;, &quot;cf-captcha-response&quot;: result[&quot;token&quot;]},\n    # Per request, not on session.headers: the next token may differ.\n    headers={&quot;User-Agent&quot;: ua} if ua else {},\n    timeout=30,\n)\nprint(resp.status_code)<\/pre>\n<\/div>\n<p>A header passed to post() is merged over the session&#8217;s defaults for that one request, so the session keeps its cookies and every later request goes out as before. Setting session.headers instead would stamp one solve&#8217;s user agent on every request that follows, including the next token&#8217;s submit. With httpx, fetch the page and submit through one httpx.Client so the cookies carry over, and pass data, headers and timeout to its post() in the same way.<\/p>\n<p>Two more rules come from how CaptchaFox checks the token on the site&#8217;s side. <a href=\"https:\/\/docs.captchafox.com\/getting-started\" rel=\"nofollow noopener\" target=\"_blank\">Each token can be verified once, and only within a short time<\/a>, so solve when you are ready to submit and submit straight away. And treat the token as opaque: do not strip, re-encode or reformat it. Some sites send it in a JSON body rather than a form post, so submit the form once by hand with DevTools open and mirror exactly what the page sends.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Step 4: retries, challenge types and timeouts<\/h2>\n<p>You do not choose which challenge CaptchaFox draws. Most solves draw nothing at all, because the browser evidence clears on its own, and when a slide puzzle appears, CapSkip usually completes it. Image-select and audio challenges are rare and are not solved: they come back as an ApiException whose message contains ERROR_CAPTCHA_UNSOLVABLE, within seconds rather than at the end of the timeout. A fresh attempt usually draws something else, so you have two ways to retry.<\/p>\n<ul>\n<li><strong>In CapSkip.<\/strong> The CaptchaFox section of the settings has Retries (0-3), at 0 by default. Raised, it redraws unsupported challenges, attempts that run out of time and browser errors on its own, and it never retries a key the site refuses. Each extra retry can add up to one Row Timeout, 150 seconds by default, to a single call, so pass a longer timeout to captchafox() when you raise it.<\/li>\n<li><strong>In your code.<\/strong> Catch the exception and call again, as below. The one catch is that a refused key also reads as unsolvable through the API, so a key used on the wrong domain gets retried too. It fails within seconds on every attempt and never once succeeds, which is the tell.<\/li>\n<\/ul>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">from capskip.exceptions import ApiException\n\n\ndef solve_captchafox(sitekey, url, attempts=3, **options):\n    for attempt in range(1, attempts + 1):\n        try:\n            return solver.captchafox(sitekey, url, **options)\n        except ApiException as exc:\n            # Select, audio and unreadable slide draws come back\n            # unsolvable; redraw. Anything else, such as a wrong\n            # API key, is final.\n            if &quot;UNSOLVABLE&quot; not in str(exc) or attempt == attempts:\n                raise<\/pre>\n<\/div>\n<p>captchafox() polls on the client&#8217;s recaptchaTimeout, 300 seconds by default, because it is a real browser session. CapSkip runs its own clock as well. A task can wait up to 250 seconds (Wait Timeout) for one of the 10 CaptchaFox threads (Max. Threads), and a single attempt gets 150 seconds (Row Timeout). With Retries at 0 and a thread free, a failed attempt reaches you as an ApiException from CapSkip well before the SDK&#8217;s 300 seconds are up; if the task queues for a long time, the SDK can reach its limit first and raise a TimeoutException instead.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Solving several tokens at once<\/h2>\n<p>AsyncCapSkip is a genuine asyncio client in Python, not an alias, so asyncio.gather runs several solves side by side. Pair it with httpx&#8217;s async client, and keep every token together with its own user agent until it is submitted.<\/p>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">import asyncio\n\nimport httpx\nfrom capskip import AsyncCapSkip\n\nsolver = AsyncCapSkip(host=&quot;127.0.0.1&quot;, port=8080)\n\n\nasync def solve_and_submit(client, sitekey, url, form):\n    await client.get(url)  # the form's cookies land in client\n    result = await solver.captchafox(sitekey, url)\n    ua = result.get(&quot;userAgent&quot;)\n    return await client.post(\n        url,\n        data={**form, &quot;cf-captcha-response&quot;: result[&quot;token&quot;]},\n        headers={&quot;User-Agent&quot;: ua} if ua else {},\n    )\n\n\nasync def main(jobs):\n    async with httpx.AsyncClient(timeout=30) as client:\n        return await asyncio.gather(\n            *(solve_and_submit(client, *job) for job in jobs),\n            return_exceptions=True,\n        )<\/pre>\n<\/div>\n<p>Two limits apply. CapSkip runs 10 CaptchaFox solves at a time by default, and the rest wait for a free thread for up to the 250 second Wait Timeout, so a gather over fifty jobs is fine at normal solve times; for bigger batches, raise Max. Threads or gather in smaller groups. And CaptchaFox scores the network as well as the browser, so many solves from one address raise the challenge rate. Configure proxies in CapSkip&#8217;s CaptchaFox section, or pass a proxy dict with a type and a uri on each call, and send the submit through the same exit. More on asyncio patterns is in <a href=\"https:\/\/capskip.com\/solve-captchas-parallel-python\/\">the guide to solving CAPTCHAs in parallel in Python<\/a>.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Running the solver on another machine<\/h2>\n<p>127.0.0.1 is right while the script and CapSkip share a Windows PC. When the Python code moves to a VPS, a container, a CI runner or a hosted notebook, loopback points at the wrong machine and the first solve raises a NetworkException. Switch CapSkip to Server mode and it listens on your network address or public IP, so any of those can call it over the same API. Use a static public IP when the route crosses the internet, turn on API key validation, and limit the port to the addresses you expect with a Windows Firewall rule. The solver is still your own Windows machine, and solves are still unmetered.<\/p>\n<p>The SDK does not read environment variables by itself. Read CAPSKIP_HOST, CAPSKIP_PORT and CAPSKIP_API_KEY in your code and pass them to the constructor, as the full example does, so the same script runs at your desk and on a server.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Full working example<\/h2>\n<div data-no-translation>\n<pre data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"># pip install &quot;capskip&gt;=1.3.0&quot; requests\nimport os\nimport re\n\nimport requests\nfrom capskip import CapSkip\nfrom capskip.exceptions import (ApiException, CapSkipError,\n                                TimeoutException, ValidationException)\n\nPAGE_URL = &quot;https:\/\/example.com\/signup&quot;\n# Copied from the script tag on MAM pages.\nMAM_PACKAGE = &quot;https:\/\/s.uicdn.com\/mampkg\/@mamdev\/core.frontend.libs.captchafox\/&quot;\n\nsolver = CapSkip(\n    apiKey=os.getenv(&quot;CAPSKIP_API_KEY&quot;, &quot;capskip&quot;),\n    host=os.getenv(&quot;CAPSKIP_HOST&quot;, &quot;127.0.0.1&quot;),\n    port=int(os.getenv(&quot;CAPSKIP_PORT&quot;, &quot;8080&quot;)),\n)\nsession = requests.Session()\n\nhtml = session.get(PAGE_URL, timeout=30).text\ntag = re.search(r'&lt;[^&gt;]*class=&quot;(?:[^&quot;]*\\s)?captchafox(?:\\s[^&quot;]*)?&quot;[^&gt;]*&gt;', html)\nkey = tag and re.search(r'data-sitekey=&quot;([^&quot;]+)&quot;', tag.group(0))\nkey = key or re.search(r'captchafox[^&quot;]*\/api\\.js\\?key=([^&quot;&amp;]+)', html)\nif not key:\n    raise SystemExit(&quot;No sitekey in the HTML; find it in DevTools.&quot;)\napi_server = MAM_PACKAGE if &quot;mampkg\/@mamdev\/core.frontend.libs.captchafox&quot; in html else None\n\ntry:\n    for attempt in range(1, 4):\n        try:\n            result = solver.captchafox(key.group(1), PAGE_URL,\n                                       api_server=api_server)\n            break\n        except ApiException as exc:\n            # Select, audio and unreadable slide draws come back unsolvable.\n            if &quot;UNSOLVABLE&quot; not in str(exc) or attempt == 3:\n                raise\n            print(f&quot;attempt {attempt}: {exc}&quot;)\nexcept ValidationException as exc:\n    raise SystemExit(f&quot;not sent: {exc}&quot;)\nexcept TimeoutException:\n    raise SystemExit(&quot;gave up waiting; recaptchaTimeout is 300 seconds&quot;)\nexcept CapSkipError as exc:\n    # A third unsolvable draw, a refused key, or CapSkip unreachable.\n    raise SystemExit(f&quot;solve failed: {exc!r}&quot;)\n\nua = result.get(&quot;userAgent&quot;)\nresp = session.post(\n    PAGE_URL,  # or wherever the form's action attribute points\n    data={&quot;email&quot;: &quot;YOUR_EMAIL&quot;, &quot;cf-captcha-response&quot;: result[&quot;token&quot;]},\n    headers={&quot;User-Agent&quot;: ua} if ua else {},\n    timeout=30,\n)\nprint(resp.status_code, &quot;UA sent:&quot;, bool(ua))<\/pre>\n<\/div>\n<p>If the solve fails instantly on every run, check the page URL before anything else, because a key used outside its registered domains fails the same way each time. When the regex finds nothing, the page builds the widget from script, and the key is in the render call or the Network tab as described in Step 1. The raw endpoint behind this method is documented in <a href=\"https:\/\/capskip.com\/api-docs\/#captchafox\">the CaptchaFox API reference<\/a>.<\/p>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">Common errors and what they mean<\/h2>\n<table>\n<thead>\n<tr>\n<th>What you see<\/th>\n<th>Cause<\/th>\n<th>Fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>The site rejects a token CapSkip returned as solved<\/td>\n<td>The submit went out as python-requests or python-httpx, not as the browser that minted the token<\/td>\n<td>Send result.get(&quot;userAgent&quot;) as the User-Agent header on that request<\/td>\n<\/tr>\n<tr>\n<td>Rejected although the user agent matches<\/td>\n<td>The page loads the MAM package and the solve used the default widget, or the reverse<\/td>\n<td>Read the script tag and set api_server to match it<\/td>\n<\/tr>\n<tr>\n<td>A KeyError on userAgent<\/td>\n<td>The solve reported no user agent, and the key is only present when it did<\/td>\n<td>Read it with result.get() and send the header only when there is a value<\/td>\n<\/tr>\n<tr>\n<td>An ApiException straight away, every time, for one key<\/td>\n<td>The page URL is outside the domains the key is registered for, or the key itself is wrong<\/td>\n<td>Send the page the widget runs on, not a redirect or a search result, and recheck the key<\/td>\n<\/tr>\n<tr>\n<td>An occasional ApiException containing ERROR_CAPTCHA_UNSOLVABLE<\/td>\n<td>CaptchaFox drew an image-select or audio challenge, or a slide variant CapSkip could not read<\/td>\n<td>Retry in code, or raise Retries in CapSkip&#8217;s CaptchaFox settings<\/td>\n<\/tr>\n<tr>\n<td>A token that worked once fails the second time<\/td>\n<td>Each token verifies once and expires quickly<\/td>\n<td>Solve a fresh token for every submit, and submit straight away<\/td>\n<\/tr>\n<tr>\n<td>More challenges, then refusals, as a run goes on<\/td>\n<td>Every solve comes from one address, and CaptchaFox scores the network<\/td>\n<td>Spread solves across a proxy pool, and submit through the same exit<\/td>\n<\/tr>\n<tr>\n<td>ValidationException before anything is sent<\/td>\n<td>An empty sitekey or URL, a keyword argument the method does not take, or a proxy type CapSkip does not accept<\/td>\n<td>Check the sitekey was found, and fix or drop the argument the message names<\/td>\n<\/tr>\n<tr>\n<td>NetworkException on the first call<\/td>\n<td>CapSkip is not running, or the host and port are wrong<\/td>\n<td>Start CapSkip, then check whether it should be in Local mode or Server mode<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">FAQ<\/h2>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Is result[&quot;code&quot;] different from result[&quot;token&quot;]?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">No, for CaptchaFox they are the same string. code is the field every CapSkip method fills, which keeps older code working unchanged, and token is the name that matches what the form expects. Use token in new code so it reads like the field it fills.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Can I use the token in a Playwright or Selenium session?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">Yes, as long as the submit goes out under the user agent CapSkip returned. Playwright fixes the user agent when a context is created, so solve first, open the context with browser.new_context(user_agent=ua), load the form, write the token into the cf-captcha-response field and submit. In Selenium with Chrome, add the user-agent switch with that value to the Chrome options before the driver starts, or switch a running session with driver.execute_cdp_cmd(&quot;Network.setUserAgentOverride&quot;, {&quot;userAgent&quot;: ua}). If your automation does not need a browser for anything else, the requests route above is simpler.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">Can a Python script on a hosted platform reach the solver?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">Yes. Put CapSkip in Server mode under connection settings so it listens on a network address instead of loopback, read that address from CAPSKIP_HOST in your script, and pass it to CapSkip(). A VPS, a container host, a CI runner and a hosted notebook all connect over the same HTTP API. Use a static public IP and a firewall rule when the route crosses the internet. The solver stays on hardware you own, so nothing changes about how solves are counted.<\/p>\n<\/details>\n<details style=\"border:1px solid #e2e5ee;border-radius:10px;padding:14px 18px;margin:0 0 12px;\">\n<summary style=\"cursor:pointer;\">\n<h3 style=\"font-size:1.15rem;line-height:1.4;display:inline;margin:0;\">How is this different from the C# version?<\/h3>\n<\/summary>\n<p style=\"margin:12px 0 0;\">The call and the rules are the same; the traps are different. In C#, HttpClient sends no User-Agent at all unless you add one. In Python, both common clients send their own name instead, python-requests or python-httpx, which a site can refuse just as easily. The .NET side is covered in <a href=\"https:\/\/capskip.com\/captchafox-csharp\/\">the C# CaptchaFox guide<\/a>.<\/p>\n<\/details>\n<h2 style=\"font-size:1.6rem;line-height:1.35;\">The short version<\/h2>\n<p>To solve CaptchaFox in Python, read the sitekey from the captchafox container, the render call or the Network tab, and note whether the page loads the MAM package. Call solver.captchafox() with the sitekey and the real page URL, adding api_server only for MAM pages. Post result[&quot;token&quot;] in cf-captcha-response with result.get(&quot;userAgent&quot;) as the User-Agent header, once and straight away. Retry unsolvable draws, add proxies as volume grows, and switch to Server mode when the script leaves the solver&#8217;s machine.<\/p>\n<ul>\n<li>How CaptchaFox works and what the solver covers: <a href=\"https:\/\/capskip.com\/captchafox-solver\/\">the CaptchaFox solver page<\/a>.<\/li>\n<li>Every CAPTCHA type the Python package handles: <a href=\"https:\/\/capskip.com\/python-captcha-solver\/\">the Python CAPTCHA solver page<\/a>.<\/li>\n<\/ul>\n<p>Retrying an image-select draw is the one habit this type needs, and with a <a href=\"https:\/\/capskip.com\/\">local captcha solver<\/a> on your own machine each retry costs a few seconds rather than another billed solve.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>requests \u548c httpx \u90fd\u4f1a\u5728 User-Agent \u8bf7\u6c42\u5934\u91cc\u62a5\u51fa\u81ea\u5df1\u7684\u8eab\u4efd\uff0c\u8fd9\u6837\u53d1\u51fa\u7684 CaptchaFox token \u53ef\u80fd\u4f1a\u88ab\u62d2\u7edd\u3002\u672c\u6587\u7ed9\u51fa\u5b8c\u6574\u7684 Python \u4ee3\u7801\uff1a\u7528 CapSkip \u8bc6\u522b\u5c0f\u7ec4\u4ef6\uff0c\u518d\u4ee5\u7b7e\u53d1\u8be5 token \u7684\u6d4f\u89c8\u5668\u8eab\u4efd\u63d0\u4ea4\u5b83\u3002<\/p>","protected":false},"author":1,"featured_media":26147,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Solve CaptchaFox in Python (requests, httpx) | CapSkip","rank_math_description":"To solve captchafox in python, call solver.captchafox(), then post the token in cf-captcha-response under the user agent it returns. Full code inside.","rank_math_focus_keyword":"solve captchafox in python","footnotes":""},"categories":[70],"tags":[],"class_list":["post-26148","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-captcha"],"_links":{"self":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/26148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/comments?post=26148"}],"version-history":[{"count":4,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/26148\/revisions"}],"predecessor-version":[{"id":26157,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/posts\/26148\/revisions\/26157"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/media\/26147"}],"wp:attachment":[{"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/media?parent=26148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/categories?post=26148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/capskip.com\/zh\/wp-json\/wp\/v2\/tags?post=26148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}