urllib.robotparser无法解析robots.txt通配符问题求助
解决urllib.robotparser解析robots.txt的通配符与转义问题
问题场景与现象
我需要检查特定URL是否允许被指定爬虫抓取,最初使用Python标准库的urllib.robotparser实现,代码如下:
import urllib.robotparser rp = urllib.robotparser.RobotFileParser("https://rus-teplici.ru/robots.txt") rp.read() print(rp.can_fetch("*", "https://rus-teplici.ru/")) print(rp.can_fetch("*", "https://rus-teplici.ru/search/?q=fd"))
但实际运行中遇到两个关键问题:
- 通配符支持缺失:无法识别
*、?、$这类标准robots.txt通配符,比如无法处理Disallow: *set_filter=规则,导致包含set_filter=的URL(如https://rus-teplici.ru/catalog/teplitsy-polikarbonat/?arrFilter_2_MIN=990&arrFilter_2_MAX=85990&set_filter=)被误判为可抓取。 - 内容转义异常:解析器读取到的robots.txt规则是URL转义后的内容:
Disallow: /%2Abitrix
Disallow: /%2Aindex.php
Disallow: %2Aset_filter%3D**
而网站实际的robots.txt规则应为:
Disallow: /*bitrix
Disallow: /*index.php
Disallow: set_filter=
解决方案
方案1:修复标准库解析的转义问题
如果坚持使用urllib.robotparser,可以手动对读取到的规则进行URL解码,还原原始通配符:
import urllib.robotparser from urllib.parse import unquote rp = urllib.robotparser.RobotFileParser("https://rus-teplici.ru/robots.txt") rp.read() # 遍历所有规则,解码转义字符 for entry in rp.entries: # 处理Disallow规则 for rule in entry.rulelines: rule.path = unquote(rule.path) # 处理Allow规则(如果有) for rule in entry.allowlines: rule.path = unquote(rule.path) # 重新检查URL权限 print(rp.can_fetch("*", "https://rus-teplici.ru/catalog/teplitsy-polikarbonat/?arrFilter_2_MIN=990&arrFilter_2_MAX=85990&set_filter="))
注意:此方法仅解决转义问题,urllib.robotparser本身仍不支持复杂通配符匹配,仅能处理前缀匹配。
方案2:使用支持通配符的第三方库
推荐使用robotexclusionrulesparser,这是一个完全遵循robots.txt标准的解析库,支持所有通配符,且自动处理URL转义:
安装依赖
pip install robotexclusionrulesparser
示例代码
from robotexclusionrulesparser import RobotExclusionRulesParser # 初始化解析器并抓取robots.txt parser = RobotExclusionRulesParser() parser.fetch("https://rus-teplici.ru/robots.txt") # 检查不同URL的抓取权限 print(parser.is_allowed("*", "https://rus-teplici.ru/")) print(parser.is_allowed("*", "https://rus-teplici.ru/search/?q=fd")) print(parser.is_allowed("*", "https://rus-teplici.ru/catalog/teplitsy-polikarbonat/?arrFilter_2_MIN=990&arrFilter_2_MAX=85990&set_filter="))
这个库能正确解析*set_filter=*这类通配符规则,返回准确的抓取权限结果。
内容的提问来源于stack exchange,提问作者Максим Акулов
相关产品推荐
相关产品推荐

