How to Avoid and Solve CAPTCHAs When Scraping
You deal with CAPTCHAs when scraping in two ways: avoid triggering them, with a per-site request budget, a slower rate, clean residential or mobile IPs, a real browser with a consistent fingerprint and cookies kept for the session, and solve the few that still appear with a solver service or a person. Avoiding comes first, because every solve costs time and money, and invisible checks such as score-based CAPTCHAs give you nothing to solve. A CAPTCHA is a signal that the site has scored you as automated: on public pages, slow down and change what triggered it; in front of a login, a sign-up or a checkout, stop (when a CAPTCHA means stop). ProxyField covers the IP side of this list with 412M+ residential IPs, from $1.95/GB; start with the Easy Trial: 1 GB for $2.95.
- residential IPs
- 412M+
- from, traffic never expires
- $1.95/GB
- Easy Trial
- 1 GB for $2.95
On this page 11 sections
- What triggers a CAPTCHA?
- How to avoid CAPTCHAs when scraping
- How to solve the CAPTCHAs you still get
- Why do I keep getting CAPTCHAs in Playwright or Selenium?
- Handling CAPTCHAs in Playwright, Puppeteer and Selenium
- reCAPTCHA, hCaptcha and Turnstile: what each needs
- Headless browsers and CAPTCHAs
- Google CAPTCHAs and the "unusual traffic" page
- How to stop seeing CAPTCHAs as a regular visitor
- When a CAPTCHA means stop
- How to Avoid and Solve CAPTCHAs When Scraping FAQ
What triggers a CAPTCHA?
A CAPTCHA appears when the site's risk check scores your request as likely automated. The score comes from five groups of signals, and a scraper usually trips more than one:
| Signal | What raises suspicion | What lowers it |
|---|---|---|
| IP reputation | Data center ranges, IPs with a history of abuse, many requests from one IP | Residential or mobile IPs, spread over many addresses |
| Request rate and pattern | Bursts, fixed intervals, hundreds of pages per minute from one session | Slower, irregular pacing; back-off on errors |
| Client fingerprint | A User-Agent that the TLS handshake or browser signals contradict; headless flags | A real browser, or a client whose TLS and headers match the browser it claims |
| Cookies and JavaScript | No cookies, no JavaScript, every request a "first visit" | Cookies kept for the session; JavaScript executed |
| Behavior | Direct hits on deep URLs, no scrolling or mouse movement on interactive pages | Natural navigation where the site expects it |
The CAPTCHA is the last step of that check, not the first. That is why the fixes below work on the signals and leave the CAPTCHA itself for last.
How to avoid CAPTCHAs when scraping
Work through the list in order; each step says when it applies.
Check the rules and set a budget before you scale. Read the site's
/robots.txtand its terms, and skip the paths it disallows. The robots.txt standard, RFC 9309 (September 2022), says its rules "are not a form of access authorization", so they are the site's request to crawlers, not a lock; follow them anyway. Set a request budget per site before the job starts: how to check if a website allows scraping.Slow down. If CAPTCHAs start after a burst, the rate is the trigger. Start at one request every few seconds per site, with random jitter, lower concurrency per site, and raise the rate only while no challenges appear.
Cache and skip what you have. Every page you don't fetch again is a request that cannot be challenged: store pages, deduplicate URLs, and re-fetch only what changed.
Spread requests over clean IPs. If one IP gets challenged while a fresh one passes, the IP's reputation or request count is the trigger. Rotate residential proxies or mobile proxies so no single IP carries much traffic; ProxyField gives a new IP on every request, or a sticky IP for 30 s to 36 h.
Keep one IP per session. If you are challenged in the middle of a session, an IP change may be the trigger. Keep a sticky IP and one set of cookies for the length of a session, and rotate between sessions, not inside one.
Make the client consistent. If a plain HTTP client is challenged at once while a browser passes, the fingerprint is the trigger. Send headers that match the client, use an HTTP client that matches a browser's TLS fingerprint, or use a real browser (TLS and TCP fingerprinting, HTTP headers for web scraping).
Run JavaScript and keep cookies. If the page sets cookies with scripts before showing content, a client without JavaScript looks new on every request. Use Playwright, Puppeteer or Selenium for those pages and reuse the browser context.
Use the data source the site offers. An official API, a data feed or a sitemap often gives the same data without any challenge.
Retry later, not harder. A challenge or a
429 Too Many Requestsis information. MDN's reference says a 429 "may" carry aRetry-Afterheader that tells you how long to wait (MDN: 429). The rule:- wait the
Retry-Aftertime when the response sends one; - otherwise wait 20 s, then 40 s, then 80 s, with random jitter;
- try at most 3 times per URL, then log it and move on;
- continue on a new session, never by repeating the same request at once.
More on rate limits: 429 Too Many Requests.
- wait the
Proxies are one step of nine. What they can and cannot change is covered in CAPTCHA proxies.
How to solve the CAPTCHAs you still get
When a CAPTCHA appears anyway on a public page, you have three ways to handle it:
- A solver service through its API. You send the CAPTCHA's details (the type, the site key and the page URL); the service returns an answer or a token; your script submits it the way the page would. Human-powered and machine-based services exist; CAPTCHA solver services compared explains how they differ.
- A person in the loop. For low volumes, pause the script, show the challenge to an operator, and continue once it is solved. This suits monitoring jobs that hit a CAPTCHA a few times a day.
- Skip the page. If one page in a thousand is challenged, log it and retry it later on a new session.
Tokens are short-lived and tied to the page. hCaptcha's documentation, for example, says a token can be redeemed once and expires after 120 seconds by default (hCaptcha docs). Solve just before you submit, on the same page and session, and through the same IP where the service supports it.
Why do I keep getting CAPTCHAs in Playwright or Selenium?
Three causes, in the order to check them:
-
The IP
Many requests from one datacenter IP, or an IP with a poor reputation, look automated before the page even loads. Use residential IPs, one sticky IP per browser context.
-
The rate
Many pages a minute from one session, at fixed intervals. Slow down and add jitter (step 2 above).
-
Headless signals
Default headless Chromium differs from a normal Chrome, and automation flags such as
navigator.webdriverare visible to detection scripts.
The test: run the same job once in headed Chrome (headless=False) through the same IP. If the CAPTCHAs stop, headless signals are the trigger; if they continue, look at the IP and the rate. Also check whether your script logs in on every run: a fresh login is a common trigger, and reusing a saved session avoids it (below).
Handling CAPTCHAs in Playwright, Puppeteer and Selenium
Browser automation does not solve CAPTCHAs by itself; it lowers how often you see them and lets you handle the rest. The pattern is the same in all three tools: detect the challenge, stop that session, back off, and continue on a new one.
Playwright. This script loads a page through the ProxyField gateway, checks for a CAPTCHA frame, and starts a new browser context (new cookies, new IP on rotation) when it finds one, with the back-off rule from step 9. Replace <login> and <password>.
import random
import time
from playwright.sync_api import sync_playwright
PROXY = {"server": "http://gate.proxyfield.io:7000",
"username": "<login>-country-us-city-new_york", "password": "<password>"}
CAPTCHA_FRAMES = "iframe[src*='recaptcha'], iframe[src*='hcaptcha'], iframe[src*='challenges.cloudflare.com']"
def fetch(url, attempts=3):
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY)
try:
for attempt in range(attempts):
context = browser.new_context() # new cookies for each try
page = context.new_page()
page.goto(url, wait_until="domcontentloaded")
page.wait_for_timeout(3000) # CAPTCHA frames load after the page
if page.locator(CAPTCHA_FRAMES).count() == 0:
html = page.content()
context.close()
return html
context.close() # challenged: drop this session
time.sleep(20 * 2 ** attempt * random.uniform(1, 1.5)) # 20 s, 40 s, 80 s + jitter
return None # 3 tries: log the URL and move on
finally:
browser.close()
print(fetch("https://example.com/") is not None)Reuse a login instead of logging in again. If your job uses an account you are entitled to, log in once and save the browser state; later runs load it, so the site does not see a new login, and the login CAPTCHA, on every run. Playwright's documentation describes this (Playwright: authentication):
# once, after logging in:
context.storage_state(path="playwright/.auth/state.json")
# every later run:
context = browser.new_context(storage_state="playwright/.auth/state.json")Playwright warns that the state file "may contain sensitive cookies and headers that could be used to impersonate you or your test account", so keep playwright/.auth out of git. Load the saved state through the same sticky session, such as <login>-country-us-city-new_york-session-he9f2qga-ttl-3600, because the same cookies arriving from a new IP can look like a session takeover. If the login itself shows a CAPTCHA every time, treat it as a stop (see below).
Selenium. Selenium does not handle CAPTCHAs itself; detect the frame, quit the driver and start a new one. Set the proxy in your driver as in the Selenium guide.
import random
import time
from selenium.webdriver.common.by import By
CAPTCHA_FRAMES = "iframe[src*='recaptcha'], iframe[src*='hcaptcha'], iframe[src*='challenges.cloudflare.com']"
def fetch(url, make_driver, attempts=3):
for attempt in range(attempts):
driver = make_driver() # a new driver: new cookies, new IP on rotation
try:
driver.get(url)
time.sleep(3) # CAPTCHA frames load after the page
if not driver.find_elements(By.CSS_SELECTOR, CAPTCHA_FRAMES):
return driver.page_source
finally:
driver.quit() # challenged or done: close this session
time.sleep(20 * 2 ** attempt * random.uniform(1, 1.5))
return NoneWith per-request rotation the new context or driver gets a new IP; with a sticky session, change the session id instead: -region-<region>, -session-<id> and -ttl-<seconds> (30 to 129,600 seconds, 20 minutes by default) after the location, as in <login>-country-us-region-new_york-city-new_york-session-he9f2qga-ttl-600. Proxy setup for each tool: Playwright, Puppeteer, Selenium. Why automated browsers get flagged in the first place: browser fingerprinting in web scraping.
reCAPTCHA, hCaptcha and Turnstile: what each needs
The common CAPTCHAs differ in what they show and in what a scraper can do about them.
| CAPTCHA | What the visitor sees | What decides the result | What helps a scraper |
|---|---|---|---|
| reCAPTCHA v2 checkbox | A checkbox, sometimes an image grid | Risk signals, then the image answer | Fewer triggers; a solver for the image step |
| reCAPTCHA v3 | Nothing | A score the site reads and acts on | Only better signals: there is no challenge to solve |
| hCaptcha | A checkbox and image tasks; passive modes on Enterprise plans | Risk signals and the answer; Enterprise sites also get a bot score | Fewer triggers; a solver for the visible tasks |
| Cloudflare Turnstile | Usually nothing, sometimes a checkbox | Small JavaScript challenges and browser signals | A real, consistent browser; a good IP |
Turnstile runs "non-interactive JavaScript challenges" and aims to avoid showing a puzzle at all; it can be embedded on any site, not only sites behind Cloudflare (Cloudflare: Turnstile). The hCaptcha row follows hCaptcha's documentation; reCAPTCHA v3's score model is described in Google's reCAPTCHA developer guide. The vendors themselves are compared in CAPTCHA providers compared.
Headless browsers and CAPTCHAs
A headless browser runs JavaScript and keeps cookies, so it passes checks that stop plain HTTP clients, but it is also easier to detect than a person's browser: default headless builds and automation flags differ from a normal Chrome in ways detection scripts test. Expect fewer CAPTCHAs than with a plain client, not none. Image and puzzle challenges still need a solver or a person.
Google CAPTCHAs and the "unusual traffic" page
Google shows its "unusual traffic" page and a CAPTCHA when a network sends too many automated searches. For rank tracking and SERP data, ProxyField's Google SERP API returns the results page as JSON, from $1.20 down to $0.80 per 1,000 successful results, billed on successful results only; contact sales. If you run your own scraper on ProxyField proxies, the rate and client rules above still apply, and Google may still show its checks.
How to stop seeing CAPTCHAs as a regular visitor
If you see CAPTCHAs while browsing, the site's check scored your connection or browser as risky:
- Turn off your VPN or proxy and reload, or switch to another network; shared VPN IPs are often flagged.
- Allow cookies and JavaScript for the site, and pause ad-blocking or privacy extensions on it.
- Update your browser.
- Restart your router if your home IP may have been flagged; many home connections get a new IP that way.
If the CAPTCHA appears on every visit, only the site can change its rule. Extensions that promise to solve CAPTCHAs for you carry risks of their own: see CAPTCHA solver extensions for Chrome.
When a CAPTCHA means stop
A CAPTCHA in front of a login, a checkout or an account sign-up protects something the site does not want automated, and getting around it on purpose can break the site's terms and raise legal risk. Scrape public pages, follow the site's terms, and ask the owner for access or an API when the data sits behind a barrier: see is web scraping legal. ProxyField's acceptable use policy forbids fake accounts and fake engagement.
The IP side of the checklist. ProxyField residential proxies: 412M+ IPs in 195+ countries, a new IP per request or sticky sessions up to 36 h, from $1.95/GB with no subscription. Start with the Easy Trial (1 GB); traffic never expires, and all purchases are final.
How to Avoid and Solve CAPTCHAs When Scraping FAQ
How do I avoid CAPTCHAs when scraping at scale?
ProxyField's 412M+ residential IPs, from $1.95/GB, cover the IP steps of avoiding CAPTCHAs at scale; the rest is your scraper's job. The 9 steps: check robots.txt and set a request budget per site, start at one request every few seconds per site with jitter, cache pages instead of re-fetching them, spread requests over clean residential or mobile IPs, keep one IP and one set of cookies per session, make the client's headers and TLS fingerprint consistent, run JavaScript where the page needs it, and use the site's API where one exists. After a challenge or a 429, wait the Retry-After time, or 20, 40 and 80 seconds, and stop after 3 tries per URL.
How do you solve a CAPTCHA?
As a person, you answer the challenge: tick the box, pick the images or type the text. In a script, you either avoid the trigger, send the challenge to a solver service and submit the token it returns, or pause for an operator to solve it.
How do I get around a CAPTCHA?
The reliable way is not to trigger it: a slower rate, clean IPs, a consistent browser and cookies kept per session. For the CAPTCHAs that still appear, use a solver service or a person, and treat CAPTCHAs on logins, sign-ups or checkouts as a sign to stop.
What triggers a CAPTCHA?
A risk check that scores the request as likely automated: an IP with a poor reputation or too many requests, a burst of traffic, a client whose fingerprint contradicts its User-Agent, missing cookies or JavaScript, or unnatural navigation. Most scrapers trip several of these at once.
Is it better to avoid CAPTCHAs or solve them automatically?
Avoid them first. Every solve adds cost and delay, tokens expire within minutes, and score-based checks such as reCAPTCHA v3 have nothing to solve; keep a solver for the small share of challenges left after the fixes.
Why do I keep getting CAPTCHAs with Playwright?
Usually because of the IP, the rate or the automation signals: default headless Chromium differs from a normal Chrome, and many requests from one data center IP look automated. Use residential IPs with one sticky IP per browser context, slow down, reuse the context's cookies, and test headed Chrome to see if headless mode is the trigger.
How do I handle the CAPTCHAs that keep showing up in my Playwright or Selenium scraper?
Detect the CAPTCHA frame after each page load, close that browser context or driver, wait 20, 40, then 80 seconds, and retry on a new session, at most 3 times per URL. Then remove the trigger: use one sticky residential IP per context, slow down, reuse a saved login with Playwright's storage_state instead of logging in on every run, and run headed Chrome once to see whether headless mode is the cause. A CAPTCHA in front of a login, sign-up or checkout is a sign to stop.
How do I handle a CAPTCHA in Selenium?
Detect it: look for the CAPTCHA iframe or the challenge page title. Then stop that session, and either retry on a new session after a delay or pass the challenge to a solver and inject the returned token. Selenium itself doesn't solve CAPTCHAs.
How do I deal with CAPTCHAs in Puppeteer?
The same way: reduce triggers with a sticky residential IP per browser context and a slower rate, detect the challenge frame after each navigation, and back off or hand it to a solver. Proxy setup for Puppeteer is on our Puppeteer integration page.
How do I avoid reCAPTCHA when scraping?
reCAPTCHA decides from risk signals, so improve them. Use residential IPs, a slow and irregular rate, a real or consistent browser, and cookies kept for the session. reCAPTCHA v3 shows no challenge at all; the site simply gets a low score, so only better signals help there.
Show 4 more questionsShow fewer questions
Can headless browsers solve CAPTCHAs?
They pass more checks than plain HTTP clients because they run JavaScript and keep cookies, but they don't solve image or puzzle CAPTCHAs, and default headless builds are detectable. Expect fewer CAPTCHAs, not none.
How do CAPTCHAs affect web scraping?
They stop the request until someone answers, so a scraper either fails, slows down or pays for solving. A rising CAPTCHA rate is also an early warning that your rate, IPs or client are being flagged.
How do I remove CAPTCHA when browsing?
You can't remove a site's CAPTCHA, but you can see it less: turn off your VPN or proxy, allow cookies and JavaScript, pause ad-blocking extensions on the site, and update your browser. If it appears on every visit, only the site owner can change the rule.
How do I pass CAPTCHA human verification?
Complete it as asked, and if it keeps coming back, fix what triggers it: a flagged VPN or network, blocked cookies or scripts, an outdated browser. Tools that promise to skip human verification for you are covered in our post on CAPTCHA solver extensions, with their risks.
Related pages
Easy Trial: 1 GB for $2.95.
Try for the price of 1 GB, no subscription, traffic never expires.