- 自动会话管理
- 锁定 195 个国家/地区的任意城市
- 无限并发会话
礼貌爬取
简而言之:礼貌爬取是指以不会影响目标服务器正常运行的速率抓取页面。它结合了请求间隔控制、并发限制、遵守 robots.txt 规则以及如实标识爬虫身份。
礼貌爬取是指以不会给目标网站带来过重负载的方式运行网页爬虫,同时完成数据采集。忽视礼貌爬取原则的爬虫可能占用目标服务器的处理能力,影响真实访客的体验,并触发封锁,导致爬取任务中断。礼貌爬取既是道德责任,也是持续采集数据的实际需要。
礼貌爬取的核心原则:
- 控制请求节奏:向同一主机连续发送请求时,主动留出间隔,通常通过爬取延迟控制。
- 限制并发量:无论爬虫的总体吞吐量有多高,都应限制同时连接到单个域名的数量。
- 遵守 robots.txt:爬取前获取并遵守目标网站的 robots.txt,包括 Disallow 规则及所有 Crawl-delay 指令。
- 如实标识身份:发送能说明爬虫身份并提供联系方式的 User-Agent。
- 安排在非高峰时段运行:如果了解目标网站的流量规律,就在其低流量时段执行大规模爬取。
- 自适应退避:当响应时间延长或错误率上升时自动放慢速度,而不是继续强行请求。
识别服务器信号:
礼貌爬虫会将目标服务器的响应视为指示,而不是障碍。延迟升高通常意味着服务器承受着压力,爬虫应在造成问题前放慢速度。429 请求过多响应是在明确要求降低请求频率,而 Retry-After 响应头会指出需要等待多久。反复出现 503 响应说明服务器运行困难,此时应完全暂停爬取,而不是频繁重试。
忽视这些信号,会让爬取行为看起来与攻击无异,也是导致 IP 被永久封锁的最快方式。
实现速率控制:
import time
import requests
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url("https://example.com/robots.txt")
rp.read()
delay = rp.crawl_delay("my-crawler") or 1.0
headers = {"User-Agent": "my-crawler/1.0 (+https://mysite.com/bot)"}
for url in urls:
if not rp.can_fetch("my-crawler", url):
continue
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 429:
wait = int(response.headers.get("Retry-After", 60))
time.sleep(wait)
continue
process(response)
time.sleep(delay)
此示例只读取一次 robots.txt,遵守其中声明的爬取延迟,跳过禁止访问的路径,并在触发速率限制时遵循 Retry-After 指示。
礼貌爬取与代理网络:
通过多个 IP 地址分发请求可以提高总体吞吐量,但并不能免除礼貌爬取的责任。无论请求来自多少个源地址,目标服务器承受的都是这些请求的总负载。爬虫通过住宅代理同时发送 500 个请求,给源站造成的负担与从一个地址发送 500 个请求相同。
在正确配置下,代理轮换的作用是避免单个 IP 累积速率限制带来的影响,同时确保爬虫整体仍遵守合理的单域名请求速率。真正需要限制的是单域名并发量,而不是单 IP 并发量。
礼貌爬取的价值:
- 持续访问:请求量保持在合理范围内的爬取任务可以运行数月;过于激进的爬取任务则可能在数小时内被封锁。
- 降低成本:被拦截的请求仍会消耗带宽和代理预算,却无法返回可用数据。
- 获得更干净的数据:承受过重负载的服务器可能返回不完整的页面、超时响应或错误页面,污染数据集。
- 降低法律风险:能够证明采集行为有所节制,有助于说明数据采集是以负责任的方式进行的。
- 减少反机器人措施升级:网站检测到负载激增后,可能部署更严格的反爬虫措施,让所有人今后的数据采集都更加困难。
大规模礼貌爬取:
大规模爬取面临的矛盾是:礼貌爬取限制了单域名吞吐量,而业务需求又要求完成大量请求。解决方法是横向扩展,而不是纵向提速:以较低速率并行爬取多个域名,而不是快速爬取单个域名。例如,对 10,000 个域名分别遵守 1 秒请求间隔,爬虫的总体吞吐量仍可达到每秒 10,000 个请求,同时不会对任何单台主机造成过重负担。
Bright Data 的爬虫 API会自动控制单域名请求节奏和并发量,让大规模爬取任务合理分配负载,无需针对每个目标网站单独调优。