应使用requests.head()替代get以节省资源,设置allow_redirects=false手动处理重定向,结合urllib.parse.urljoin补全相对路径,捕获connectionerror、timeout及非2xx状态码,并输出含原始位置、属性值和状态码的完整报告。

如何用 Python 批量检测 href/src 是否指向 404
直接发起 HTTP 请求是判断资源是否失效最可靠的方式,但必须规避全量 GET(太慢)、忽略相对路径(会错判)、绕过重定向陷阱(302 后仍是 404)。关键不是“能不能访问”,而是“最终响应是不是 2xx”。
- 用
requests.head()替代requests.get(),减少带宽消耗;设置allow_redirects=False,避免被跳转掩盖真实状态 - 对
href或src值做路径补全:若值为./js/app.js,需结合当前 HTML 文件路径或<base href>构造绝对 URL,否则requests会当成根路径请求 - 捕获三类失败:
ConnectionError(域名不可达)、Timeout(超时)、非 2xx 状态码(含 301/302 后未跟进的终点 404) - 输出格式建议包含原始标签位置(
line:123)、属性值、最终状态码、错误类型,方便定位和批量修复
修复时为何不能直接删掉失效的 href/src 属性
删掉 href 或 src 不等于解决问题——它可能让页面逻辑断裂。比如 <link rel="stylesheet" href="missing.css"> 被删后,样式彻底丢失;<script src="vendor.js"></script> 缺失可能导致后续 JS 报 ReferenceError。
- 优先尝试替换为备用 CDN 地址(如将
https://cdn.example.com/jquery.min.js换成https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js) - 对 CSS/JS 类资源,可加 fallback 逻辑:
<script src="a.js" onerror="this.src='b.js'"></script> - 对图片,用
onerror回退到占位图:<img src="bad.jpg" onerror="this.src='/img/placeholder.png'"> - 绝对不要无条件删除属性——除非你确认该资源本就不该存在(如注释掉的调试代码)
为什么正则替换 href/src 值容易出错
HTML 属性值可能跨行、含引号嵌套、混有 JS 表达式(如 href="${url}"),纯正则无法安全解析结构。曾见有人用 href="([^"]*)" 替换,结果把 <a href="x" onclick='alert("href=xxx")'></a> 中的 href=xxx 也替换了。
- 必须用解析器(如
BeautifulSoup或lxml)提取属性,而非字符串匹配 -
BeautifulSoup默认不校验 HTML 合法性,遇到<img src="">这种缺值情况会返回空字符串,需额外判空 - 修改后写回文件时,注意保持原有编码(尤其是含中文路径时),否则
src="中文路径.js"可能变成乱码 - 若 HTML 含模板语法(如 Vue 的
v-bind:href或 Nunjucks 的{{ url }}),解析器会误判为普通属性,需先剥离模板再处理
上线前必须检查的三个隐藏雷区
自动化修复脚本跑通不代表线上安全——很多失效是环境导致的,本地检测不出。
-
file://协议下所有href/src请求都会被浏览器拦截(Edge 尤其严格),本地测试时即使链接有效,上线后也可能 404;务必在 HTTP 服务下验证(如python -m http.server) - 某些 CDN 对 Referer 有限制,
requests.head()默认无 Referer,而浏览器实际请求带 Referer,导致检测“可用”但用户端“失效” - 零宽字符(如
\u200B)可能藏在href值开头或结尾,肉眼不可见,但会让 URL 变成无效地址;检测前应先用re.sub(r'[\u200B-\u200F\u202A-\u202E]+', '', value)清洗
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











