拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Python后端爬虫专题09:服务器返回200也不代表该抓——robots.txt与域名访问策略

Python后端爬虫专题09服务器返回200也不代表该抓——robots.txt与域名访问策略上一篇练习完整答案base_delay0.5、max_attempts3 时第一次失败后等 0.5 秒第二次失败后等 1 秒第三次失败直接抛错因为已无下一次尝试。HTTP-date 可以用email.utils.format_datetime构造未来时间断言 delay 落在合理区间400 调用 1 次503 最多 3 次429 同样有限但等待不少于 Retry-After。fromjobradar.http_clientimportRetryPolicy policyRetryPolicy(max_attempts3,base_delay0.5)assertpolicy.delay_for(1,None)0.5assertpolicy.delay_for(2,None)1.0assertpolicy.delay_for(1,2)2.0robots.txt 能做什么不能做什么robots.txt 告诉自动客户端哪些路径希望被访问。TargetLab 对 JobRadarBot 允许/jobs、拒绝/admin。RobotsRespectingFetcher 首次访问来源站时下载规则之后缓存若路径被拒绝不发送页面请求。它不能授予版权、个人信息处理或商业使用许可也不是认证系统。攻击者可以忽略 robots所以真正私有数据必须用鉴权保护。采集方也不能把“robots 没写 Disallow”解释为无限制授权。为什么 allowlist 必须在服务端JobRadar API 接收 seed_url。如果只在前端下拉框限制调用者可直接 POST 任意地址让 Worker 访问内网管理页这就是 SSRF。CrawlPolicy 在服务器端检查 scheme、host 和凭据不在 allowed_hosts 中的域名在网络请求前被拒绝。allowlist 不是url.startswith(https://target.test)。https://target.test.evil.example会通过错误前缀判断https://target.testevil.example中前半段是用户名。必须解析 URL 后比较标准化 hostname。DNS 解析后的第二次检查一个看似公开的域名可能解析到 127.0.0.1、10.0.0.0/8、链路本地或云元数据地址。Worker 使用 getaddrinfo 得到所有地址再调用check_resolved_addresses。只要有一个危险地址且该 host 未被明确允许就拒绝。课程 Docker 中 TargetLab 的服务名解析到私网容器地址所以配置同时声明allowed_seed_hoststargetlab与allowed_private_hoststargetlab。这不是关闭保护而是对一个具体主机的明确例外。不要写allow_privatetrue让全部内网开放。DNS 重绑定还存在解析检查与实际连接之间的时间差。高安全生产实现可使用已验证 IP 建立连接并校验证书/Host或在网络层用 egress proxy 和防火墙限制目标。应用层检查是必要防线但不是唯一防线。robots 缓存与变化每个详情都下载 robots 会增加目标压力所以按 origin 缓存。长期运行的 Worker 还应设置 TTL 并在规则获取失败时选择保守策略。课程实现为了清晰在对象生命周期内缓存任务结束对象销毁下次任务重新读取。robots 返回 404 时怎么做需要项目决策RobotFileParser 通常认为没有限制但企业环境可能选择失败关闭。无论哪种都要记录规则 URL、状态和策略版本不能静默猜测。本篇检查点.\.venv\Scripts\python.exe-m pytest tests\test_robots_fetcher.py::test_robots_wrapper_denies_path_without_requesting_it-qRecordingFetcher 记录实际请求。期望列表里只有/robots.txt绝不能包含/admin/users这证明规则不仅“算出 False”而且真正阻止了网络副作用。真实调用路径Worker 装配HttpFetcher → RobotsRespectingFetcher → Crawler。外层先获取规则允许后才调用底层底层仍做 URL/DNS/响应大小检查。两者顺序清楚robots 表达目标站意愿CrawlPolicy 表达本系统授权与安全范围。不要把 robots 解析塞入 HTML parse_detail它与内容结构无关也不要让每个 Spider 自行写一套 allowlist。边界集中后HTTPX、Scrapy 和未来适配器才不会出现不同安全标准。本篇完整 robots 适配器在真实页面请求前读取并缓存每个来源站的 robots.txt。fromtypingimportProtocolfromurllib.parseimporturlsplitfrom.http_clientimportFetchResultfrom.policyimportRobotsRulesclassFetcher(Protocol):asyncdeffetch(self,url:str,*,etag:str|NoneNone,last_modified:str|NoneNone,)-FetchResult:...classRobotsDenied(PermissionError):目标站通过 robots.txt 声明当前路径不应被该爬虫访问。classRobotsRespectingFetcher:缓存同一来源的规则底层 fetcher 仍负责网络安全与重试。def__init__(self,fetcher:Fetcher,*,user_agent:str)-None:self._fetcherfetcher self._user_agentuser_agent self._rules:dict[str,RobotsRules]{}asyncdeffetch(self,url:str,*,etag:str|NoneNone,last_modified:str|NoneNone,)-FetchResult:partsurlsplit(url)originf{parts.scheme}://{parts.netloc}rulesself._rules.get(origin)ifrulesisNone:responseawaitself._fetcher.fetch(origin/robots.txt)rulesRobotsRules.from_text(response.text,user_agentself._user_agent,originorigin)self._rules[origin]rulesifnotrules.can_fetch(url):raiseRobotsDenied(frobots.txt denies path:{parts.path})returnawaitself._fetcher.fetch(url,etagetag,last_modifiedlast_modified)本篇课后练习给 RobotsRespectingFetcher 连续请求两个 jobs断言 robots 只下载一次。解释target.test.evil.example与target.testevil.example的实际 hostname。为公司内部授权站写一份范围清单来源、允许路径、频率、保留期限和联系人。下一篇会把“同一 URL 抓了两次”变成数据库层可证明的幂等行为。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门