无需 KYC —— 无需身份证、自拍、文件证明。支持加密货币支付:BTC, USDT, USDC, ETH, SOL, LTC
语言: 简体中文
开始使用

指南 · 负责任爬取 · 2026

403、429 和 CAPTCHA:响应,而非绕过

403、429 或 CAPTCHA 是网站向您的爬虫发出的信号。正确的回应几乎总是放慢速度,阅读规则,或提出请求;错误的是伪装爬虫。这里教您如何将正确的回应写入代码。

最后更新:

快速回答

爬虫应如何处理 403、429 和 CAPTCHA 响应?

将它们视为信号,而非障碍。在 429 时,等待 Retry-After 并降低该主机上的请求频率。遇到 403,暂停后重试一次,若仍失败则停止并检查网站规则。遇到 CAPTCHA,停止访问该主机,不要自动破解。 CrawlRelay 住宅代理,来自 US$0.50/GB,分散负载并设定位置;它们不是绕过网站限制的方法。无需 KYC。支持加密货币支付。

三种信号一览

429 请求过多您爬取太快。遵守 Retry-After,退避,降低每主机并发请求数
403 禁止访问请求被拒绝。暂停后重试一次,然后停止并检查
CAPTCHA 或挑战页面网站想确认您是否为真人。停止访问该主机并放慢速度
爬取规则规范robots.txt,RFC 9309;Crawl-delay 是常用扩展
我们不支持的内容CAPTCHA 破解,隐身插件,指纹伪装

每个信号对我的爬虫意味着什么?

  • 429 是最礼貌的信号:内容可用,但速度过快。RFC 6585 定义了它,通常带有指明何时重试的 Retry-After 头。
  • 403 是请求被拒绝。可能是可修复的(地区错误,缺少 header,请求过快)或最终拒绝(网站不允许自动访问该内容)。
  • CAPTCHA 或挑战页面,通常伴随 403 或 503 状态码,表示网站的反爬机制怀疑您的流量。这是比忽略的 429 更严厉的升级措施。

这三者都是递增的信号。忽略 429 后,网站会升级到 403 和挑战,最终对整个 IP 段进行长时间封禁,影响该段所有用户。

每个信号爬虫该如何应对?

信号首次响应若持续出现停止条件
429等待 Retry-After 或带随机性的指数退避该主机请求数减半若 Retry-After 越来越长,或 429 持续单请求返回
403暂停后重试一次,同国家对比同国家浏览器访问,检查 robots.txt 和条款同一 URL 模式第二次出现 403
CAPTCHA / 挑战暂停该主机数分钟以更低速率恢复低速下仍出现挑战,代表网站不允许自动访问
503 携带 Retry-After按要求等待暂停该主机多数请求失败超过几分钟

如何构建正确响应的爬虫?

将规则放在抓取器里,而非每个爬虫。该抓取器每主机一次只发一个请求,遵守 robots.txt 及其 Crawl-delay,等待 Retry-After,连续三次拒绝后停止访问。它将 4xx robots.txt 视为允许,5xx 视为完全禁止,符合 RFC 9309 规范。

Python:礼貌的抓取器
import time
import urllib.robotparser
from urllib.parse import urlsplit

import requests

PROXY = "http://USERNAME-country-us:[email protected]:7777"
USER_AGENT = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"


class PoliteFetcher:
    """One request at a time per host; robots.txt, Crawl-delay and Retry-After honoured."""

    def __init__(self, min_interval=1.0, max_refusals=3):
        self.min_interval, self.max_refusals = min_interval, max_refusals
        self.http = requests.Session()
        self.http.proxies = {"http": PROXY, "https": PROXY}
        self.http.headers["User-Agent"] = USER_AGENT
        self.robots, self.next_time, self.refusals = {}, {}, {}

    def _robots(self, root):
        if root not in self.robots:
            rp = urllib.robotparser.RobotFileParser(root + "/robots.txt")
            try:
                r = self.http.get(root + "/robots.txt", timeout=(10, 30))
                if r.status_code >= 500:
                    rp.parse(["User-agent: *", "Disallow: /"])  # unreachable: assume disallow
                else:
                    rp.parse(r.text.splitlines() if r.status_code == 200 else [])  # 4xx: allowed
            except requests.RequestException:
                rp.parse(["User-agent: *", "Disallow: /"])
            self.robots[root] = rp
        return self.robots[root]

    def get(self, url):
        scheme, host = urlsplit(url)[:2]
        if self.refusals.get(host, 0) >= self.max_refusals:
            return None  # this host said no: stop asking
        rp = self._robots("%s://%s" % (scheme, host))
        if not rp.can_fetch(USER_AGENT, url):
            return None
        delay = max(self.min_interval, rp.crawl_delay(USER_AGENT) or 0)
        wait = self.next_time.get(host, 0) - time.monotonic()
        if wait > 0:
            time.sleep(wait)
        r = self.http.get(url, timeout=(10, 30))
        pause = delay
        if r.status_code in (429, 503):
            retry_after = r.headers.get("Retry-After", "")
            pause = max(delay, int(retry_after) if retry_after.isdigit() else 60)
        refused = r.status_code in (403, 429) or "captcha" in r.text[:5000].lower()
        self.refusals[host] = self.refusals.get(host, 0) + 1 if refused else 0
        self.next_time[host] = time.monotonic() + pause
        return r


fetcher = PoliteFetcher()
resp = fetcher.get("https://example.com/")
print(resp.status_code if resp is not None else "skipped")

如何合法修复 403?

部分 403 原因在您这边,修正它们是合理的:

  • 地区错误。 许多网站仅对特定区域提供服务。使用 -country-<code> 针对目标国家。
  • 缺失 Header。 发送 Accept,Accept-Language 和带联系 URL 的真实用户代理。仅 HTTP 客户端使用类浏览器 User Agent 不一致,常被拒绝。
  • 请求速度过快。 N 次请求后出现 403 是速度问题,应放慢。

不能算修复的是:频繁切换 User Agent 装作不同用户、伪造浏览器指纹、或者更换 IP 以绕过网站故意设置的封禁。如果网站过滤托管 IP 段以屏蔽自动流量,使用住宅代理 IP 并不能让访问合法。

为什么不直接解决 CAPTCHA?

因为 CAPTCHA 是网站提出一个问题,而你可能会误答。自动解决会把一个礼貌的爬虫变成一个专门绕过访问控制的工具,这会增加你的法律风险:2026 年美国关于搜索抓取案件,如 Google 诉 SerpApi 和 Reddit 诉 SerpApi 等,涉及被告绕过反自动化系统违反 DMCA 的反规避条款。法院对此尚无定论,但风险是真实存在的。

CrawlRelay 不支持 CAPTCHA 解决或反机器人检测,且其可接受使用政策] 已禁止通过网关使用这些功能。如果你需要访问受挑战保护的数据,请向网站申请访问权限,使用其 API,或许可数据。

我什么时候应该联系网站?

当你需要超过网站默认允许的访问时。许多网站提供 API、数据源、合作伙伴计划,或者对能够自报身份并说明用途的爬虫提高限制。在你的用户代理里放入联系 URL,保持公开一页介绍你的爬虫和退出方式,及时响应滥用报告。能被联系的爬虫在被封锁前会收到警告。

403,429 和 CAPTCHA:常见问题

住宅代理能阻止 CAPTCHA 吗?

别指望它。住宅出口 IP 会改变网站看到的 IP,而不是你的爬虫行为:因请求频率或行为而触发的 CAPTCHA 依然存在,这是网站的本意。如果低频请求仍被挑战,说明网站不欢迎自动访问该内容。

如果 429 状态码没有 Retry-After,我该等多久?

从几秒开始,遇到每个新的429时将等待时间翻倍,同时加一点随机延迟,最多等约一分钟。当请求恢复成功,按触发 429 前的较低频率恢复爬取,随后在错误率稳定时慢慢提高速率。

轮换 IP 来规避速率限制允许吗?

轮换有助于分散负载并选择不同地区,是正常做法。但用轮换来维持低于单 IP 限制的请求频率,同时保持网站拒绝的速率,是规避手段。大多数使用条款禁止此行为,我们的可接受使用政策也禁止。

我的爬虫应该发送什么用户代理?

用你自己的:包含名字、版本和可说明爬虫及联系方式的 URL,例如 ExampleCrawler/1.0 (+https://example.com/crawler-info)。不要用其他爬虫的名字,比如 Googlebot 或 GPTBot。

来源 (4)
  1. RFC 9309:机器人排除协议 — IETF (2022-09)
  2. RFC 6585:新增 HTTP 状态码(429) — IETF (2012-04)
  3. Reddit 诉 SerpApi LLC 案件 — Loeb & Loeb (2026-08)
  4. Google 诉 SerpApi 案件:法院同意我们的撤诉请求 — SerpApi (2026-07-21)

礼貌爬虫的住宅代理

US$1.50,1 GB起,US$0.50/GB从50 GB起。

从 US$0.50/GB 开始 · 无需 KYC

开始使用