跳到主内容

网页死链批量检测 - 免费把页面上打不开的链接一次挑出来(爬虫工具)

免费下载网页死链批量检测 v1.0.0
平台:Windows 10/11 (64位)大小:11.7 MB版本:v1.0.0更新:
提取码:fkg5(如提示需要,请输入)
下载地址 ▾
解压后双击即可运行,无需安装任何运行环境;只在你点击抓取时访问你填写的网址,其余数据都在本机处理。
网站改版或过了一年,页面上挂的外链悄悄失效,一条条点开去验要花掉一下午

网页死链批量检测 运行界面

软件名称网页死链批量检测
版本v1.0.0
授权免费(可自由使用与转发)
运行方式本地运行,仅抓取时访问你填写的网址
所属分类爬虫工具

这个工具解决什么问题

网站改过版、换过域名,或者只是过了一年,页面上那些外链就会悄悄失效:合作方的网站关了、引用过的文章被删了、图片被搬到了别的路径、域名过期了。麻烦在于它不会报错,也永远不会有人提醒你 —— 直到某个访客点上去,看到一个 404。做一次链接体检本不难,难的是量:一个内容页可能有几十个链接,一个站几百个,一条条点开、记下哪个坏了、再回头去改页面,认真做完就是一下午起步。更别说很多链接坏得并不明显:有的跳到一半才 404,有的服务器直接超时把浏览器晾在那里,有的证书过期了浏览器先拦一道警告。人工检查时,这些细枝末节基本都是漏的,最后的结果往往是「大概看了一下,应该没问题」——而问题恰恰藏在没看的那几条里。

  • 原来的做法:把页面上几十个链接挨个点开看;坏了的凭记忆记在便签上;过一阵再改页面时已经忘了哪个是哪个;有的链接要等它转圈半分钟才知道是超时
  • 用这个工具:把网页地址贴进去点一次「开始检测」,程序自动抓取页面、提取页面上全部链接、并发逐个探测,几十秒后一张表列清每条链接的真实状态(正常/跳转后正常/死链/超时/域名失效/证书错误/被 robots 拦下),红色的一眼挑出来,还能一键导出 CSV 存档
  • 省下来的:把一下午的逐条点击压缩成一次点击,而且比人做得更细:连「跳到一半才 404」「服务器超时」「证书过期」这些人工容易漏的情况都能分类列清,改完页面还能再跑一遍复查

技术实现

整个工具只用 Python 标准库(urllib + ssl + socket + http.client + html.parser + threading + concurrent.futures + csv + tkinter),运行期不需要安装任何依赖,打包后是单个 exe,双击即用。技术上有六个刻意的取舍:第一,不引 requests、不引 beautifulsoup —— 需要的能力(HTTP GET、跟随跳转、提取 <a href>)标准库完全够用,引这两个库会让单文件 exe 体积翻几倍;第二,探测用 GET 而不是 HEAD,因为现实里大量站点对 HEAD 返回 405/403/501,会造成大批假死链;第三,只读前 2KB 就断开连接,拿到状态码即可,不把对方几 MB 的页面拖回来;第四,并发只跨域名并行,同一域名强制拉开请求间隔,测几十个链接也不会把对方服务器打一顿;第五,抓取前先读目标站的 robots.txt,被明确禁止的路径压根不发请求,并在结果里说明「为什么没测」;第六,界面与核心逻辑彻底分离,核心层不 import 任何 GUI 库,因此可以脱离窗口跑全自动回归测试(180 项断言)。

  • 链接规范化:不统一就没法去重,会把同一个地址测好几遍:同一张图在页面里可能有 8 种写法(/a/b.png、a/b.png、../a/b.png、HTTP://A/B.PNG#x)。normalize_url() 做四件事:协议与域名转小写而路径大小写保持原样(很多服务器路径是大小写敏感的)、丢掉 #fragment 但保留 query(/post?id=1 与 ?id=2 是不同页面)、去掉默认端口(http://a.com:80/x → http://a.com/x)、空路径补成 /。同时把 mailto: / javascript: / tel: / data: / 纯 #锚点 全部剔除(链接体检时这些占相当比例,不剔除结果里会满屏「探测失败」)。手工输入模式还支持裸域名补全:用「点号后缀不是常见文件扩展名」来区分 example.com 与 about.html,避免把相对文件名误当成域名。
  • HTML 解析:用状态机而不是正则:用标准库 html.parser.HTMLParser 而不是正则。正则遇到属性换行、单双引号混用、注释里的假标签就会出错,而 HTMLParser 是真正的流式状态机。三个细节:convert_charrefs=True 让 &amp; 自动还原成 &(否则 /a?x=1&amp;y=2 探测必然失败);页面若声明了 <base href> 就以它为基准还原相对地址,否则会还原错;锚文本收集走 handle_data 累积 + 结束标签时归并空白,<a> 里套 <span> 也能正确拼出文字。缺失 </a> 的畸形页面在收尾时会把残留链接吐出来,不丢数据。
  • HTTP 探测:GET 而不是 HEAD,只读 2KB 就断:看上去 HEAD 更省流量,但现实里大量站点对 HEAD 返回 405 / 403 / 501,甚至直接断连,会造成大批假死链;GET 最接近用户点开链接时的真实行为。拿到响应后只 read(2048) 就关闭连接 —— 状态码已经到手,没必要把对方整个页面拖下来。另外,urllib 会把 4xx/5xx 抛成 HTTPError 异常,但它其实是一次**成功的探测**,状态码就是结论,代码里单独分支处理,不能和「连不上」混为一谈。
  • 重定向链记录:301 不是错误,但值得提醒:urllib 默认静默跟随跳转,我们自定义 _RedirectRecorder(HTTPRedirectHandler) 记录每一次 redirect_request,于是能报出「经过 N 次跳转,最终地址是 XXX」。这对链接体检很有价值:跳转后仍然 200 的链接不算坏,但页面上的旧地址早该更新了;同时 max_redirections = 8 可避免被跳转死循环拖住(两个页面互相跳)。跳转链实例每次请求都新建,不能复用 —— 探测是并发的,共用实例会让不同线程的跳转链互相污染。
  • 同域名限速 + 跨域名并发:快,但不给对方添麻烦:ThreadPoolExecutor 负责并发,HostPacer 负责礼貌:每个域名维护一个「下次可发车时间」,请求前先抢发车权,抢不到就等到时间点。跨域名照常并行(测 10 个不同站点仍是并发速度),同域名则被强制拉开间隔(默认 1.2 秒)。不做这一步的话,几十个链接会同时打到同一台服务器上,等于一次小型攻击,也容易被封 IP。停止按钮通过 threading.Event 通知,已发出的请求等它返回、未开始的直接跳过,结果列表长度始终与入参一一对应,界面上不会出现「幽灵行」。
  • robots.txt 合规:被禁止就压根不发请求:抓取前先读目标站的 robots.txt,按主流搜索引擎的「最长前缀优先」策略判定(Allow / Disallow 里挑前缀最长的,长度相同时 Allow 优先),并按站点缓存结果 —— 一个页面上的几十个链接往往在同一域名下,逐条去读 robots 等于白给对方几十倍请求。规则点名的 User-agent 分组优先于通配分组。被禁止的路径直接给出「已跳过(robots 禁止)」的结果并说明原因,不发请求 —— 这才是「遵守 robots」的实际含义,而不是先抓了再道歉。读不到 robots.txt 时按允许处理(连 robots.txt 都没有的站点本来也没有禁止声明)。
  • 网络异常全部翻译成人话,GUI 里看不到堆栈:图形界面程序没有控制台,用户永远看不到 Python 的 Traceback,所以每一种网络异常都必须变成人话:域名无法解析(域名拼错/已停用/DNS 异常)、连接被拒绝(端口没开或被防火墙拦截)、请求超时(对方响应太慢)、证书校验不通过(证书过期或域名不匹配)、TLS 握手失败、连接被对方中断。实现上 isinstance 的顺序很关键 —— SSLError / gaierror / TimeoutError 都是 OSError 的子类,必须先判子类再判 OSError,否则全部会被归到「无法连接」。界面上另有「忽略证书错误」开关,应对那些证书过期但内容还在的老站点。

技术栈:Python 3.8+、零第三方依赖(纯标准库)、tkinter 图形界面、urllib + ssl + socket 探测 HTTP 状态、html.parser 提取页面链接、ThreadPoolExecutor 并发 + 同域名限速、PyInstaller 单文件打包

已知局限:只解析静态 HTML,内容完全由 JavaScript 渲染出来的链接抓不到(不会去执行 JS)。robots 判定不支持 * 与 $ 通配符,当普通字符处理。不做递归爬取,只测「你填的页面」这一层。无法判断「页面返回 200 但内容已经换成别的东西」这类软失效(那属于内容比对,不在本工具范围)。链接很多时,受同域名限速影响,总耗时是线性的(这是刻意的礼貌取舍,可以通过调低「同域名间隔」加快,但不建议设为 0)。单条链接的耗时取决于对方站点的响应速度,视机器与网络而定。

操作教程

  1. 双击打开程序
    解压后双击「网页死链批量检测.exe」,不需要安装 Python 或任何依赖。
    预期结果:出现主窗口,自上而下是 ①要检测什么、②检测方式与选项、③开始检测、④检测结果
  2. 填入要检测的网址
    在 ① 的输入框里粘贴网址,一行一个;也可以点「从文件导入…」选一个 .txt / .csv(带序号、带引号、带列表符号的行都能识别)。
    预期结果:网址出现在输入框里,底部提示「已从文件导入 N 个网址」
  3. 选择检测方式
    整理收藏夹、核对外链 → 选「检测这些链接本身」;网站改版后做外链体检 → 选「抓取这些页面并检测页内链接」。后者会把每个地址当网页打开、提取页面上所有 <a> 链接,再逐个探测。
    预期结果:单选按钮切换即时生效,无需其它设置
  4. 按需调整选项(默认值可用)
    「只显示有问题的」勾上后表格只留有问题的行;「忽略证书错误」应对证书过期的老站点;「同时检测图片/脚本等资源」会把 img/script/iframe 的地址也一起测;「遵守 robots.txt」默认勾选,建议保持。并发数/超时/同域名间隔都有默认值,不懂就別动。
    预期结果:改动即时生效;勾选「只显示有问题的」后表格行数立刻变化
  5. 点「开始检测」
    程序在后台并发探测,进度条前进、状态栏显示当前正在检测哪条链接;中途可以点「停止」。
    预期结果:抓取模式下先看到「正在读取页面并提取链接……」,随后进度条按 N/N 推进,窗口全程不卡死
  6. 看结果,挑出红色的
    结果表格按「结果 / 状态 / 链接 / 耗时 / 锚文本 / 说明」六列展示。绿色正常、橙色跳转后正常、红色有问题、灰色主动跳过。双击任意一行可在浏览器里打开;选中多行点「复制选中链接」或右键复制。
    预期结果:红色行就是需要修掉的死链,鼠标悬在说明列能看到具体原因(如「证书已过期」「跳转到 https://…」)
  7. 导出 CSV 存档、改完页面再复查
    点「导出 CSV」把当前显示的结果存成表格(带 UTF-8 BOM,Excel 双击打开不乱码),点「打开导出目录」直接跳到文件所在位置。
    预期结果:CSV 文件生成并可正常打开;改完页面后再跑一遍,红色行应当消失

常见问题

Q:「检测这些链接本身」和「抓取这些页面并检测页内链接」有什么区别?A:前者把你填的每一行当一条**待检测的链接**,直接探测它的状态;后者把你填的每一行当**一个网页**,先抓这个页面、解析出页面上所有 <a> 链接(勾了选项还会带上图片/脚本),再逐个探测,并把页面自己也一起测掉。前者用于整理收藏夹、核对交付文档里的外链;后者用于网站改版后的外链体检。
Q:为什么有的链接显示「已跳过(robots 禁止)」?A:因为目标站的 robots.txt 明确声明不允许抓取那个路径(例如腾讯的 wpa.qq.com/msgrd)。程序在发请求之前就把它拦下了 —— 这是刻意为之的合规行为,不是程序坏了。如果你想强制检测这类地址,可以取消勾选「遵守 robots.txt」,但请确认你有权这么做。
Q:橙色「跳转后正常」算不算坏链接?A:不算,链接现在还能打开,只是它经过了 301/302 跳转。说明列里会告诉你跳了几次、最终落到哪个地址。建议顺手把页面上的旧地址换成最终地址,省掉访客的一次额外跳转,也避免哪天对方把老地址彻底关掉。
Q:结果可靠吗?会不会把能打开的链接误报成死链?A:探测用的是 GET(而不是 HEAD)并跟随跳转,最接近浏览器真实行为,误报率很低。少数情况仍需人工确认:站点对非浏览器 UA 做了拦截(例如返回 403 防盗链)、需要登录才可见的页面(401)、或者对方正好在维护(5xx)。这几类在说明列里都会写清原因,一眼能看出来不是真的死链。
Q:测几十个链接会不会把对方网站弄挂、或者把我的 IP 封掉?A:不会。同一个域名的两次请求之间被强制拉开间隔(默认 1.2 秒),并发只发生在不同域名之间;一次操作只处理你填的那几个页面,不递归、不翻页。另外默认会先读目标站的 robots.txt,被明确禁止的路径不发请求。
Q:一个页面才几十个链接,为什么要等十几秒?A:因为限速。程序刻意不做「同域名并发」——同一个域名下的链接必须排队,每条之间隔 1.2 秒,这是为了不给对方服务器造成压力。嫌慢可以把界面上「同域名间隔」调小(比如 0.5),但请确保你有权这么做。跨不同域名的链接是并发的,所以外链很多的页面反而跑得更快。
Q:支持 GBK 编码的老网站吗?导出的 CSV 在 Excel 里会乱码吗?A:都处理了。编码按 BOM → HTTP 头 charset → HTML meta 声明 → UTF-8 → GB18030 的顺序嗅探,gb2312 / gbk 一律按 gb18030 解码(超集,遇到生僻字也不会失败)。导出的 CSV 带 UTF-8 BOM,Excel 双击打开中文不乱码。导入 txt/csv 清单时同样支持 GBK。
Q:数据会上传到你们服务器吗?A:不会。程序只在点击「开始检测」时访问你自己填写的那些网址,除此之外不向任何第三方发送数据;检测结果只保存在你导出的 CSV 里,程序本身不写任何上传接口。

技术实现与后续维护

本工具由我们自行开发并持续维护,每次迭代都在本地跑过完整自测(180 项断言,含对本地测试服务的真实 HTTP 端到端探测)。核心逻辑与界面彻底分离:链接规范化、HTML 解析、robots 判定、HTTP 探测、并发调度、CSV 导出都是可独立调用的纯函数,因此后续无论换界面、换导出格式还是加新检测项,改动都不会牵一发动全身。合规相关的能力(robots 判定、同域名限速)被做成流程里的一等公民,任何新增的「发请求」行为都会经过它们。

技术构成:

  • src/link_checker_gui.py —— 程序入口:tkinter 窗口布局、事件绑定、后台线程与消息队列调度、筛选与 CSV 导出
  • src/link_core.py —— 核心逻辑(不含任何界面代码):链接规范化、HTML 链接提取、robots.txt 判定、HTTP 探测与错误翻译、并发调度与同域名限速、统计与 CSV 生成
  • src/demo_server.py —— 本地测试服务:内置 200 / 301 / 404 / 500 / 极慢 / robots 禁止 六类路径,供自测与演示使用
  • src/selftest.py —— 自测脚本:180 项断言,覆盖规范化和解析、robots 判定、编码嗅探、错误分类、CSV 转义、以及对本地服务的真实 HTTP 端到端探测

运行环境:

Windows 10/11 64 位。运行版是单个 exe,不需要安装 Python、不需要装任何依赖,解压双击即用。程序需要联网(只在检测时访问你自己填写的网址)。界面基于 Python 标准库自带的 tkinter 构建,运行时无需任何第三方包。

可扩展方向:

  • 递归爬取整站:增加「深度」选项,顺着站内链接往下爬,做真正的全站体检
  • 站点迁移批量替换:把旧域名批量替换成新域名试测,直接产出需要改的链接清单
  • 结果基线对比:把每次检测存成基线,下次只报「新增的死链」,便于定期复查
  • 软失效识别:在状态码之外增加「页面标题是否变化」,识别返回 200 但内容已被替换的链接
  • 体检报告导出:生成带分类统计与图表的 HTML / Markdown 报告,可直接发给客户
  • 定时体检:配合 Windows 任务计划程序每天自动跑一次,发现死链发提醒

本工具免费提供使用,但不对外分发源码。如果你需要在本工具基础上做功能调整、对接内部系统或长期维护,可以联系我们做二次开发,源码与工程文档可在定制合作中一并交付。

需要其它功能?可以定制

这个工具只做一件事:网站改版或过了一年,页面上挂的外链悄悄失效,一条条点开去验要花掉一下午。如果你的场景还需要别的处理,可以联系我们做二次开发,按你的实际数据格式和流程定制。

常见的定制需求:

  • 递归爬取整个站点(含 sitemap.xml 导入),输出按页面分组的死链清单
  • 网站迁移场景:把全站旧域名的链接批量替换成新域名试测,给出需要替换的清单
  • 对接你们内部的 CMS 或数据库,检测完直接标出需要改的页面 ID
  • 每天定时跑一次并把新增死链发到邮箱或群机器人
  • 把结果写进你们自己的表格/看板,而不是导出 CSV 手动导入
  • 联系方式:邮箱/微信见站内「联系我们」页面,或在本文下方留言
  • 定制说明:请附上你的数据样例(脱敏即可)和期望结果,方便快速评估工作量
  • 交付形式:定制项目可交付可执行程序,按需一并交付源码与工程文档,支持长期维护

使用说明与免责声明

本工具涉及数据采集,请在合法合规的前提下使用。
  • 本工具仅用于采集公开可见或你自身拥有权限的数据。
  • 请遵守目标网站的服务条款、robots 协议及《网络安全法》等相关法律法规。
  • 请合理控制请求频率,不要对目标站点造成访问压力。
  • 不得用于采集个人隐私、付费墙内容或任何受法律保护的非公开数据。
  • 因使用不当造成的后果由使用者自行承担;本工具不做数据二次分发。
免费下载网页死链批量检测 v1.0.0
平台:Windows 10/11 (64位)大小:11.7 MB版本:v1.0.0更新:
提取码:fkg5(如提示需要,请输入)
下载地址 ▾
解压后双击即可运行,无需安装任何运行环境;只在你点击抓取时访问你填写的网址,其余数据都在本机处理。
分享到:

本文链接:https://www.biyeyuanma.cn/post/271.html

服务热线

加我微信

加我微信