快速回答
代理中的429 Too Many Requests是什么意思?
429 请求过多 意味着网站限速:你发送的请求数超过了单位时间内它可接受的数量。解决方法是减少请求数量,而非隐藏请求数量。使用 CrawlRelay 住宅代理时,请遵守 Retry-After 头,限制每个主机的并发数,并执行带随机抖动的指数退避。旋转 IP 超过网站公布的限制会违反大多数使用条款。
429 Too Many Requests一览
| 错误 | 429 Too Many Requests |
|---|---|
| 类型 | HTTP 状态码(4xx,客户端错误) |
| 发送方 | 目标网站或其 API 网关 |
| 定义于 | RFC 6585, section 4 (Retry-After: RFC 9110, section 10.2.3) |
| 要重试吗? | 是的,在 Retry-After 延迟之后或指数退避后 |
| 先检查 | 读取 Retry-After 头和每个主机的每秒请求数 |
429 Too Many Requests是什么意思?
RFC 6585 引入了 429 用于限速。服务器可添加一个 Retry-After 头,包含秒数或 HTTP 日期,告知何时重试。API 通常还会加自己的头,比如 X-RateLimit-Remaining。
429 是网站给爬虫最礼貌的答复,表示内容可用,只是当前访问速度过快。忽视 429 的网站往往升级为 403、验证码或永久禁封。
在Python、curl、Node.js和浏览器中a 429是什么样?
每个工具中相同的失败会有不同的提示信息。请在日志中搜索以下信息:
- Python requests / httpx:
status_code == 429,通常带有Retry-After: 30 - Scrapy: 通过默认的
RetryMiddleware处理,因为 429 包含于默认的RETRY_HTTP_CODES - curl: 响应头包含
HTTP/2 429和retry-after: - API: 返回类似
{"error": "rate_limited"}的 JSON 内容
导致a 429的原因是什么?
最可能的首要原因:
- 每主机并发过多。 50 个并行工作者对同一域名对大多数网站来说像攻击。
- 请求间无延迟,或者固定延迟让多个工作者在同一时刻请求。
- 重试无退避。 首个 429 后重试风暴加重负载。
- 共享限额。 有些网站计数按账号、API 密钥或会话 Cookie,而非 IP。
- 重负载接口。 搜索和筛选 URL 通常限额比静态页面严格。
如何一步步诊断a 429?
- 记录第一个 429 的
Retry-After值及任何速率限制头。 - 测量你对每个主机的实际请求率,而非总请求率。
- 检查限额是否基于 IP、Cookie 或 API 密钥:逐个更换。
- 阅读网站 API 或 robots.txt 文档,
Crawl-delay行会说明期望的访问速率。
# Use the URL that fails; with https://api.ipify.org instead, you test the gateway alone.
# "HTTP/1.1 200 Connection established" first, then the site's own status: the site answered.
curl -v -x http://USERNAME:[email protected]:7777 https://TARGET_URL
# Same test through the SOCKS5 port, with DNS resolved at the exit
curl -v --socks5-hostname gw.crawlrelay.com:7778 --proxy-user USERNAME:PASSWORD https://TARGET_URL如何修复a 429?
- 遵守 Retry-After。 至少等待服务器要求的时间。
- 限制每个主机的并发数,不仅是全局。Scrapy 有
CONCURRENT_REQUESTS_PER_DOMAIN和AUTOTHROTTLE_ENABLED设置。 - 指数退避并加抖动: 1 秒、2 秒、4 秒递增,加上随机分数,设置最大上限。
- 减少抓取量。 缓存响应,发送
If-Modified-Since或If-None-Match,跳过未变更页面。 - 使用官方 API。 网站提供时,限额通常有文档说明。
import random
import time
import requests
PROXY = "http://USERNAME:[email protected]:7777"
PROXIES = {"http": PROXY, "https": PROXY}
RETRY_STATUSES = {429, 502, 503, 504}
def fetch(url, attempts=5, timeout=(10, 30)):
for attempt in range(attempts):
try:
r = requests.get(url, proxies=PROXIES, timeout=timeout)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
r = None # dropped exit, reset or timeout: a new connection gets a new exit
if r is not None and r.status_code not in RETRY_STATUSES:
return r
retry_after = r.headers.get("Retry-After", "") if r is not None else ""
if retry_after.isdigit():
wait = int(retry_after)
else:
wait = min(60, 2 ** attempt) + random.uniform(0, 1)
time.sleep(wait)
raise RuntimeError("giving up on %s after %d attempts" % (url, attempts))遇到a 429后要重试吗?
是的,429 设计为可稍后重试。若服务器发送 Retry-After 延迟,请等待此时长;否则使用带抖动和上限的指数退避。记录连续的 429 次数并降低该主机的并发数。以下 Python 函数实现了基本功能。
429 Too Many Requests如何应用于CrawlRelay?
通过 CrawlRelay 到达你的 429 带有目标服务器自己的头和内容:限额是网站设置的,每主机速率控制由你负责。某些网站按会话计数请求,用粘性会话保持速率可测量。参考 并发指南 获取初始参数。
网关:gw.crawlrelay.com,端口7777(通过CONNECT的HTTP、HTTPS)和端口7778(SOCKS5)。用户名格式:USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}。相关内容:403 禁止访问 · 503 服务不可用 · 并发指南。
429 Too Many Requests:开发者常问的问题
我应该旋转 IP 来避免 429 吗?
不。429 是网站请求你减速。将同样速率分散到更多 IP 下以规避单 IP 限制叫做绕过,大多数使用条款禁止。IP 轮换适用于负载均衡和地理位置,不用于突破公布限额。降低请求速率,尽量缓存响应。
收到 429 后应等待多久?
等待 Retry-After 头指定的秒数或日期。无头时,从一两秒开始,每遇到一次 429 将延迟翻倍,加随机时间,最大约一分钟。重启时降低速率,而非原速。
为什么我每分钟只有几次请求就会遇到 429?
限额可能按账号、Cookie 或 API 密钥而非 IP,或者接口开销大,如搜索页面。有些网站对被分类为爬虫的客户端设置了低限额。检查响应头和 API 文档,有需要时联系网站申请更高访问权限。
本参考中的其他代理错误
HTTP 状态码
- 401 Unauthorized vs 407
- 403 Forbidden
- 407 Proxy Authentication Required
- 429 Too Many Requests
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
浏览器和客户端错误
连接和 TLS 错误
带有涵盖失败案例文档的住宅代理
来自US$0.50/GB的CrawlRelay住宅代理,流量永不过期。