ROBOTSTXT_OBEY 打开后 Scrapy 具体怎么做?什么时候下载 robots.txt、下载失败怎么办、按哪个 User-agent 匹配、Crawl-delay 管不管?这篇用一个能返回各种 robots.txt 的服务器逐项实测。
默认值(ROBOTSTXT_OBEY、ROBOTSTXT_PARSER、ROBOTSTXT_USER_AGENT):False scrapy.robotstxt.ProtegoRobotParser None 项目模板 settings.py 里的相关行:#USER_AGENT = "proj (+http://www.yourdomain.com)" | ROBOTSTXT_OBEY = True
内置默认关闭,项目模板打开。打开后 RobotsTxtMiddleware 在每个请求前先取该 netloc 的 robots.txt(优先级 1000),解析后缓存,之后同一个 netloc 的请求直接用缓存的解析器。
/a 通过
/b 通过
/private 被拒:IgnoreRequest: Forbidden by robots.txt
/private/x 被拒:IgnoreRequest: Forbidden by robots.txt
/privatefoo 被拒:IgnoreRequest: Forbidden by robots.txt
服务器收到的顺序:['/robots.txt', '/a', '/b'];robotstxt stats {'forbidden': 3, 'request_count': 1, 'response_count': 1, 'response_status_count/200': 1}不被允许的请求抛 IgnoreRequest("Forbidden by robots.txt"),不会发出,计入 robotstxt/forbidden;errback 能收到。
默认 USER_AGENT /all:通过 /free:通过 /mybot-only:通过 /scrapy-only:拒 ROBOTSTXT_USER_AGENT=mybot /all:通过 /free:通过 /mybot-only:拒 /scrapy-only:通过 USER_AGENT=mybot/1.0 (+http://x) /all:通过 /free:通过 /mybot-only:拒 /scrapy-only:通过
用 ROBOTSTXT_USER_AGENT(没设就用请求的 User-agent)去匹配 robots.txt 的组;存在匹配的具体组时 * 组不生效。
robots.txt 的情形 /private robotstxt stats / 说明
200 正常 被拒 {'forbidden': 1, 'request_count': 1, 'response_count': 1, 'response_status_count/200': 1};服务器收到 robots.txt 1 次
404 通过 {'request_count': 1, 'response_count': 1, 'response_status_count/404': 1};服务器收到 robots.txt 1 次
500(会被重试 2 次) 通过 {'request_count': 1, 'response_count': 1, 'response_status_count/500': 1};服务器收到 robots.txt 3 次
超时(服务器睡 2 s,超时 0.5 s) 通过 {"exception_count/<class 'scrapy.exceptions.DownloadTimeoutError'>": 1, 'request_count': 1};服务器收到 robots.txt 1 次
200 但是 1024 字节二进制垃圾 通过 {'request_count': 1, 'response_count': 1, 'response_status_count/200': 1};服务器收到 robots.txt 1 次robots.txt 下载失败(404、5xx、超时)或内容无法解析时,所有请求都被允许。
到达服务器的时刻(相对第一个请求,秒):/robots.txt@0.00, /a@1.02, /b@1.02, /c@1.03;总耗时 1.03 s meta dont_obey_robotstxt=True 的请求既不下载 robots.txt 也不受它限制(/private/x 本来会被拒绝):服务器收到 ['/private/x'],总耗时 0.01 s(robots.txt 要 1.0 s 才返回,但没有被请求)
robots.txt 下载期间,同一个 netloc 的其它请求会等待它;dont_obey_robotstxt 的请求例外。
Crawl-delay: 2 → 四个页面请求之间的间隔(ms):[1, 1, 1](没有等 2 秒);总耗时 0.01 s 同一个主机 127.0.0.1 的两个端口:服务器 1 收到 ['/robots.txt', '/x'],服务器 2 收到 ['/robots.txt', '/x'];robotstxt/request_count = 2
Scrapy 不使用 Crawl-delay,要控制节奏用 DOWNLOAD_DELAY 或 AutoThrottle。