爬取延迟

简而言之:爬取延迟是爬虫向同一主机连续发送请求时,两次请求之间等待的时间。它以非官方 robots.txt 指令的形式声明,由爬虫在客户端执行。

爬取延迟用于控制请求节奏。延迟值为 5 表示爬虫完成一次请求后,会等待 5 秒再向该主机发送下一次请求。这项指令是礼貌爬取最直接的体现。由于服务器无法强制客户端等待,是否遵守该指令取决于爬虫自身。

robots.txt 指令:

User-agent: *
Crawl-delay: 10
Disallow: /admin/

User-agent: MyCrawler
Crawl-delay: 2
Disallow:

延迟值按用户代理组分别声明。标识为 MyCrawler 的爬虫需等待 2 秒,其他爬虫则需等待 10 秒。这项指令从未纳入最初的 robots.txt 规范,也不在 2022 年将该协议标准化的 RFC 9309 范围内。尽管如此,它仍被广泛使用。

爬虫支持情况:

爬虫 是否遵守 Crawl-delay 说明
Googlebot 否 抓取频率可在 Search Console 中设置,也会自动调整
Bingbot 是 也可在 Bing Webmaster Tools 中配置
Yandex 是 有文档明确说明支持
Scrapy 是 通过 DOWNLOAD_DELAY 和 ROBOTSTXT_OBEY 实现
自定义爬虫 视实现而定 必须显式实现

Google 不支持这项指令是有意为之,并非疏漏。Googlebot 会根据观测到的服务器响应时间自行调整抓取频率,在延迟升高时放慢速度。其理由是,固定声明的数值无法反映服务器的实时状况。

如何选择延迟值:

目标网站类型 建议延迟 理由
大型商业网站 0.5–1 秒 基础设施完善,日常流量较高
中型网站 1–3 秒 承载能力适中,爬虫负载较为明显
小型或自行托管的网站 5–10 秒 资源有限,爬虫可能造成较大负载
已在 robots.txt 中声明 使用声明的数值 网站运营者已明确表达偏好
收到 429 响应后 遵循 Retry-After 服务器已给出明确指令

延迟与爬取时长:

延迟会直接影响任务完成时间,而这种影响往往被低估。以 1 秒延迟顺序爬取 100,000 个页面,大约需要 28 小时;延迟为 5 秒时,耗时接近 6 天;延迟为 10 秒时,则接近 12 天。

因此,设置延迟时不能脱离整体爬取架构。兼顾礼貌爬取和吞吐量的方法,是跨主机并行,而不是对单个主机提高请求频率。例如,同时爬取 10,000 个域名,并对每台主机设置 1 秒延迟,就能获得较高的总体吞吐量,同时每台服务器每秒只会收到一个请求。

爬取延迟与速率限制的区别:

这两种机制经常被混淆。爬取延迟由客户端自行执行,属于自愿遵守:爬虫选择等待。速率限制则由服务器强制执行:服务器会拒绝超过阈值的请求,通常返回 429 请求过多。

爬虫可以忽略爬取延迟,却无法忽略速率限制,因为超出限制的请求会直接失败。遵守声明的延迟值,是爬虫避免触发强制速率限制的主要方式之一。

实现按主机设置延迟:

from collections import defaultdict
import time

next_allowed = defaultdict(float)

def fetch_with_delay(url, host, delay):
    wait = next_allowed[host] - time.monotonic()
    if wait > 0:
        time.sleep(wait)

    response = requests.get(url, timeout=10)
    next_allowed[host] = time.monotonic() + delay
    return response

为每台主机分别记录下次允许发送请求的时间,而不是每次请求后让整个爬虫等待,这样就能在等待某台主机时继续处理其他主机。这与 URL 待爬取队列中的后端队列层采用相同的原理。

Bright Data 的爬虫 API会自动读取并遵守已声明的爬取延迟,并在目标服务器出现负载压力迹象时调整请求节奏。

准备好开始了吗?