死链检测不能只靠requests.get()加超时,因真实网站存在重定向、反爬响应、cdn缓存、登录态依赖和js渲染等干扰,直接请求易漏判404或误报正常链接;需结合状态码、响应内容、跳转终点、标题关键词及robots.txt等多层判定。

死链检测不能只靠 requests.get() 加个超时就完事——真实网站有重定向、反爬响应、CDN缓存、登录态依赖、JavaScript 渲染等干扰,直接发请求会漏掉大量 404 或误报正常链接。
为什么用 requests 批量 GET 容易漏判死链
常见现象:脚本返回 200,但页面实际是「内容不存在」提示页(如 Nginx 404 页面被配置成返回 200);或返回 302 跳转到错误页,但没继续跟进;又或者目标站用 JavaScript 动态加载内容,requests 拿不到真实状态。
- 服务器可能对爬虫 UA 返回 200 + 自定义错误 HTML,需检查
response.text中是否含「not found」「404」「页面不存在」等关键词 - 必须手动处理跳转链:设置
allow_redirects=False,再用response.headers.get('Location')判断最终目标是否可达 - 遇到
429 Too Many Requests或403 Forbidden不代表链接死,可能是反爬,应记录并跳过,而非标记为 dead - 超时时间建议设为
timeout=(3, 7)(连接 3 秒,读取 7 秒),太短会误判慢速合法页面,太长拖垮整体耗时
如何从 HTML 中提取完整待测链接(不只是 a[href])
只抓 <a href="..."></a> 会漏掉 <link rel="canonical">、<script></script> 里拼接的 URL、JSON-LD 中的 @id、甚至内联 CSS 的 url() 调用——这些都可能是有效入口或跳转源。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 用
lxml.html解析比BeautifulSoup更快,且支持 XPath 精准定位:tree.xpath('//a[@href]/@href | //link[@href]/@href | //script/text()') - 对
<script></script>内容做简单正则提取(如r'https?://[^\s"'\'']+'),不追求 100% 准确,先覆盖高频拼接模式 - 所有相对路径必须补全:用
urllib.parse.urljoin(base_url, href),别用字符串拼接 - 过滤明显无效协议:
javascript:void(0)、tel:、mailto:、data:,但保留https?和空协议(//example.com)
怎么让检测结果真正可用(不是一堆 HTTP 状态码)
原始状态码意义有限。一个 200 可能是真实内容,也可能是 404 模板页;503 可能是临时维护,也可能是永久下线。需要分层判定。
- 第一层看状态码:排除
200、301、302(且跳转目标可达)为“疑似存活” - 第二层看响应体:对
200响应,用lxml.html.fromstring(response.text).xpath('//title/text()')提取标题,若含「404」「Error」等词,标为soft_dead - 第三层看跳转终点:对
301/302,必须递归请求Location直到非重定向响应,终点是4xx/5xx才算真死链 - 输出结构建议用 CSV,字段包括:
url、status_code、final_url(跳转终点)、title、is_dead(布尔)、reason(如 "302→404" 或 "200 but title contains 'Not Found'")
并发控制与反爬绕过要平衡(别被封 IP)
开 100 个协程扫一个站,大概率触发 Cloudflare 验证或 IP 封禁;但单线程扫几千链接又太慢。得在速度和稳定性间卡住临界点。
- 用
asyncio.Semaphore(5)控制并发数,5 是多数中小型站的安全阈值;对大型站(如 WordPress 博客)可压到 2–3 - 每请求间隔加随机延迟:
await asyncio.sleep(random.uniform(0.5, 2.0)),避免规律性请求 - UA 必须轮换:准备 3–5 个真实浏览器 UA 字符串,每次请求随机选一个;别用默认
python-requests - 忽略证书验证(
ssl=False)仅限内网或测试环境;生产中遇到自签名证书应捕获ssl.SSLCertVerificationError单独处理,而非全局关验证
最常被忽略的是重定向链深度限制——有些站故意设 10 层跳转,不加 max_redirects=3 会导致无限循环或超时。还有就是 robots.txt 检查,不是所有网站都欢迎你扫,先读一次 /robots.txt 看 Disallow 规则,至少尊重基础约定。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










