as5w(如提示需要,请输入)
这个工具解决什么问题
做电商和内容的人都遇到过这种场面:活动要上线了,把商品表导到页面上,主图位置一片空白,点开一看是灰底裂图。回头查表,那张图是半年前从别处复制过来的地址,对方早就换了目录。麻烦的地方在于这一类问题完全不会报错:Excel 里那一列看起来正常,单元格里就是一串 https 开头的地址,既不标红也不提示;只有真的被浏览器加载一次,才知道它已经 404。表里几十行还好,挨个点一遍十几分钟;几百行、几千行就是纯粹熬时间。更糟的是有几类失效特别隐蔽——地址不是打不开,而是先跳转两次才 404;或者服务器一直转圈直到超时;或者干脆返回一个防盗链提示页,看着是能打开的。人工一条条点,这些基本全漏,最后交出来的结论通常是「大概看了一下,应该没问题」。
- 原来的做法:在 Excel 里点开每一条图片链接,看浏览器能不能显示;坏的凭记忆记在便签上;遇到跳转要看地址栏才知道最终落到哪;超时的链接得干等半分钟;几百行做完就是一下午,还容易被记混
- 用这个工具:选中表格文件点一次「开始检测」,程序自动把表里所有 http(s) 图片地址找出来、并发逐条探测,几十秒后一张表列清每条链接的真实状态(正常 / 跳转后正常 / 不是图片 / 死链 / 超时 / 域名失效 / 连接被拒 / 证书错误),有问题的行整行标红并按原表行号定位,还能一键导出 CSV 存档
- 省下来的:把一下午的逐条点击压成一次点击,而且分得比人工细:连「跳到一半才 404」「响应超时」「返回的是网页不是图片」这几类人工最容易漏的情况都能单独列出来,改完图床还能再跑一遍复查
技术实现
整个工具只用 Python 标准库(zipfile、xml.etree、csv、json、urllib、ssl、socket、threading、concurrent.futures、tkinter),运行期不需要安装任何依赖,打包后是单个 exe,双击即用。四个刻意的取舍:第一,xlsx 不去引 openpyxl,而是自己按 OOXML 规矩拆 zip 读 XML —— 需要的能力(取工作表名单、取单元格文本)标准库完全够用,引第三方库会让单文件 exe 变大、也埋下版本冲突的隐患;第二,探测不只用 HEAD,而是 HEAD 优先、被拒就换 GET 复测,因为现实里大量图片 CDN 对 HEAD 返回 403/405/501,只用 HEAD 会把正常图误报成死链;第三,并发只跨域名并行,同一域名强制拉开请求间隔,一个表里几百张图常常挂在同一台 CDN 上,不拉开间隔等于对它发起一次小型攻击;第四,界面与核心逻辑彻底分离,核心层不 import 任何 GUI 库,因此能脱离窗口跑全自动回归测试(60 项断言,含对本地 HTTP 服务的真实请求)。
- xlsx 自己拆 zip 解析,不引第三方库:xlsx 本质就是「若干 XML 打成的一个 zip」,解析链路是:zipfile 打开 → 读 xl/workbook.xml 拿工作表名与顺序 → 读 xl/_rels/workbook.xml.rels 把 <sheet r:id="rIdN"> 映射到具体的 xl/worksheets/sheetN.xml → 读 xl/sharedStrings.xml 还原文本 → 逐 <c> 单元格取值。这里有个不能省的细节:工作表在 zip 里的物理顺序和界面上看到的标签顺序不一定一致(用户在 Excel 里拖拽过标签就会不一致),所以必须按 rels 映射找,不能直接假设 sheet1.xml 就是第一个标签页。文本单元格大多数存成 t="s" + 一个整数索引,真正的文字在共享字符串表里,而且 <si> 内部可能有多个 <r><t> 富文本分段,要全部拼起来;否则带加粗或变色的单元格会读成空。
- 探测 HEAD 优先、GET 兜底:这一个分支决定了误报率:看上去 HEAD 更省流量,但现实里大量图片 CDN 对 HEAD 直接返回 403 / 405 / 501,甚至断开连接。如果只用 HEAD,一个正常图床的几百张图会整批被标成死链,工具等于废掉。所以探测先发 HEAD,状态码落在 {400, 403, 405, 406, 501} 就自动改用 GET 复测,并在说明列标注「HEAD 被拒,已改用 GET 复测」,让用户知道这条结论是怎么来的。GET 兜底时带 Range: bytes=0-0,只取第一个字节 —— 状态码到手结论就确定了,没必要把对方几 MB 的图整个拖回来。
- HTTPError 不是错误,是结论:urllib 会把 4xx/5xx 抛成 HTTPError 异常,但那其实是一次成功的探测,状态码本身就是我们要的结果。代码里把 HTTPError 单独分支处理,绝不能和「连不上」混进同一个 except。同时异常判断的 isinstance 顺序很关键:SSLError / gaierror / TimeoutError 都是 OSError 的子类,必须先把子类判掉,否则域名解析失败、证书过期、请求超时会被统一归成笼统的「无法连接」,用户看到这句话根本不知道该改什么。
- 并发只跨域名,同域名强制限速:ThreadPoolExecutor 负责并发,HostPacer 负责礼貌:每个域名维护一个「下次可发车时间」,请求前先抢发车权,抢不到就等到时间点。跨域名照常并行(十几张不同站点的图仍然是并发速度),同域名则被强制拉开间隔(默认 0.3 秒)。等待切成 0.1 秒小片,这样点「停止」能立刻生效,而不是干等到某一批全部返回。结果按入参下标写进固定长度的数组,保证结果条数与待检测清单一一对应,界面上不会出现「幽灵行」。
- 列自动识别:不用按固定列名排布表头:每个客户表的列名都不一样(主图、主图链接、图片地址、image_url…),所以不按列名匹配,而是按「这一列里出现 http(s) 链接的行数占比是否达到 30%」来识别链接列,识别出来的列在界面上默认勾选好。阈值取 30% 而不是 100%,是因为真实表格常有空行和「暂无」;也不能低到一两条,否则备注里偶然提到一个网址的列会被误勾。链接提取本身用正则抓 http/https,并把运营从聊天工具复制时连带带上的中文括号、句号、引号剥掉 —— 不剥就会把本来正常的链接判成 404。
- 一条烂链接不该拖垮整个扫描:实测踩到的坑:http.client 在拼请求头时用 latin-1 编码主机名,如果表格里有一条中文域名的地址,会抛 UnicodeEncodeError —— 它是 ValueError 的子类,不属于 OSError,普通网络异常分支接不住,会直接把整个并发扫描线程带崩。现在分两道防线:probe() 里先把非 ASCII 域名转成 punycode(转不了就原样走),末尾再挂一个 except Exception 兜底,把任何意外都降级成「这一条请求失败」;check_targets() 的 worker 里还有第二层保护,因为 worker 抛异常会让 fut.result() 炸掉整个批次。
- 自带本地演示服务,示例数据完全离线:「载入示例数据」不是指向公网图片:程序会在本机 127.0.0.1 上起一个随机空闲端口的 HTTP 服务,覆盖八种典型响应(正常 PNG / 302 跳转 / 404 / 410 / 403 / 500 / 返回 HTML 页 / 延迟 6 秒),再就地造一份指向它的 xlsx 并走正常的解析路径读进来。好处是三点:断网也能演示、十几毫秒出结果、每次结果都一样(截图和验收都靠它)。顺带把「写 xlsx」这件事也自己实现了 —— 只写内联字符串、省掉共享字符串表,几十行代码,还顺带给解析器做了一次端到端验证。
技术栈:Python 3.8+、运行期零第三方依赖(纯标准库)、tkinter 图形界面、zipfile + xml.etree 自解析 xlsx、urllib + ssl + socket 探测 HTTP 状态、ThreadPoolExecutor 并发 + 同域名限速、PyInstaller 单文件打包(--noconsole)
已知局限:只解析静态表格里的文本链接,不解析单元格里嵌入的图片对象本身(只认地址,不认浮动在格子上的图)。不做递归爬取,也不执行 JavaScript。无法判断「地址能打开但图片内容已经被换成另一张」这类软失效(那属于图像比对,不在本工具范围)。表格极端巨大(几十万行)时,界面控件的渲染会成为瓶颈,建议先按列拆分成几个文件分批跑。总耗时取决于对方站点的响应速度,视机器与网络而定;受同域名限速影响,同一图床上的链接多时总耗时是线性的(这是刻意保留的礼貌取舍,可以调小「同域名间隔」,但不建议设为 0)。
操作教程
- 双击打开程序
解压后双击「Excel 图片链接可用性检查.exe」,不需要安装 Python 或任何依赖。想先看效果可以直接点「载入示例数据」。
预期结果:出现主窗口,自上而下是 ①选择表格文件、②检测选项、③操作按钮、④检测结果 - 选择表格文件
点「选择表格文件…」,在系统文件对话框里选 .xlsx / .csv / .json。表格里只要有 http(s) 开头的图片地址就行,列名叫什么无所谓。
预期结果:文件名出现在输入框里,右侧「表格概况」显示格式、数据行数、列数、识别到的链接列与可检出链接条数 - 确认要检查哪些列
程序自动识别出含链接的列并帮你勾选好。如果有列没被识别到(比如图片地址写在备注里),在「要检查哪些列」里按住 Ctrl 手动加选。xlsx 还可以在下拉里切换工作表。
预期结果:选中的列在列表框里高亮;切换工作表后概况与列选择会重新加载 - 看一眼检测选项(默认值可直接用)
「同时检测数」默认 8、「超时」默认 10 秒、「同域名间隔」默认 0.3 秒。绝大多数情况不用改。图片地址在证书有问题的老站点上时,勾上「忽略证书错误」。
预期结果:数值框可以直接输入或点上下箭头微调,改动立即生效 - 点「开始检测」
程序在后台并发探测,进度条前进、状态栏显示已完成与总数;中途可以点「停止」,已发出的请求等它返回、未开始的直接跳过。
预期结果:结果表格逐行出现,窗口全程不卡死;正常行浅绿、有问题行浅红 - 挑出红色行处理
结果表按「表格行 / 所在列 / 图片链接 / 检测结果 / 状态码 / 耗时 / 说明」展示。表格行就是它在原表里的行号,照着回去改那一个单元格即可。双击任意一行会用浏览器打开该链接确认;右键可复制链接。勾上「只显示有问题的」可以只看需要处理的。
预期结果:红色行即失效链接;看「说明」列能知道具体原因(如 文件不存在(404)、域名解析不了、返回的是 text/html 不是图片) - 导出 CSV 存档、改完再复查
点「导出 CSV」把这些结果存成表格(带 UTF-8 BOM,Excel 双击打开不会中文乱码),点「打开导出目录」直接跳到文件位置。把表里的坏地址替换掉之后再跑一遍,红色行应当清空。
预期结果:CSV 生成并可正常打开;复查时红色行数量下降或归零
常见问题
技术实现与后续维护
本工具由我们自行开发并持续维护,每次迭代都会在本地跑完一整套回归测试(60 项断言,其中 HTTP 相关用例全部打在本地临时服务上,断网也能复现)。核心逻辑与界面彻底分离:表格解析、链接提取、HTTP 探测、错误分类、并发调度、CSV 导出都是可独立调用的纯函数,所以后续无论是换界面、加新的输入格式还是调整结果分类,改动都不会牵一发动全身。两处已知的坑(中文域名导致编码异常、非 HTTPError 的意外把扫描线程带崩)都已经修掉并写进回归用例,改代码时不会被重新引入。
技术构成:
src/image_url_check_core.py—— 核心逻辑层(不含任何界面代码):xlsx / csv / json 解析、链接提取与列识别、HTTP 探测与错误翻译、并发调度与同域名限速、统计与 CSV 导出src/image_url_check_gui.py—— 程序入口:tkinter 窗口布局、事件绑定、后台线程与队列调度、结果上色、筛选与导出src/demo_server.py—— 本地演示服务:内置正常 / 跳转 / 404 / 410 / 403 / 500 / 非图片 / 超时 八类响应,供示例数据与自测使用src/make_sample.py—— 示例数据生成器 + 极简 xlsx 写出器(只写内联字符串,几十行代码完成 zip 与 XML 组装)src/selftest.py—— 无界面回归测试:60 项断言,覆盖表格解析往返、链接提取与列识别、以及对本地服务的真实 HTTP 端到端探测
运行环境:
Windows 10/11 64 位。运行版是单个 exe,不需要安装 Python、不需要装任何依赖,解压双击即用。程序需要联网(只在检测时访问你表格里填写的那些网址)。界面基于 Python 标准库自带的 tkinter 构建,运行时无需任何第三方包;打包时必须带 --noconsole,否则会多出一个控制台黑框。
可扩展方向:
- 写回原表:检测完直接把结果写回原 xlsx 的相邻单元格,不用手工对照行号修改
- 批量替换试测:把旧域名批量替换成新图床域名先试测,一次性产出需要替换的清单
- 增量复查:把每次结果存成基线,下次只报本次新出现的坏链接,适合长期维护的表
- 支持更多来源:从飞书多维表格 / 腾讯文档表格 / 数据库直接取 URL
- 软失效识别:在状态码之外增加图片尺寸或内容是否被替换的比对
- 结果报告:生成带统计图表的 HTML 或 Excel 报告,可直接发给客户或团队
本工具免费提供使用,但不对外分发源码。如果你需要在本工具基础上做功能调整、对接内部系统或长期维护,可以联系我们做二次开发,源码与工程文档可在定制合作中一并交付。
需要其它功能?可以定制
这个工具只做一件事:商品表里的图片地址换过图床、改过目录、对方站点下架,失效了也不会有人告诉你,直到上线当天看到一片裂图。如果你的场景还需要别的处理,可以联系我们做二次开发,按你的实际数据格式和流程定制。
常见的定制需求:
- 接入你们自己的图床或对象存储,检测时顺带把失效图片重新上传并回填新地址
- 检测完直接写回原表格,省掉人工按行号对照修改这一步
- 每天定时跑一遍指定表格,发现新增坏链接就发到企业微信或钉钉群
- 把结果推进你们内部的商品管理系统,标出需要下架或换图的 SKU
- 支持读取飞书多维表格或腾讯文档表格,免去每次手工导出的步骤
- 联系方式:邮箱/微信见站内「联系我们」页面,或在本文下方留言
- 定制说明:请附上你的数据样例(脱敏即可)和期望结果,方便快速评估工作量
- 交付形式:定制项目可交付可执行程序,按需一并交付源码与工程文档,支持长期维护
使用说明与免责声明
- 本程序只在执行任务时访问你自己填写的地址,不向任何第三方服务器上传数据,结果只保存在本机。
- 涉及文件改写的功能,请在使用前备份原始文件。
- 软件完全免费,可自由使用与转发,请勿用于倒卖。
- 因误操作造成的数据问题请自行承担。
检测结果仅供参考:返回 403 可能是对方开启了防盗链、401 可能是页面需要登录、5xx 可能是对方正在维护,这些情况建议手动点开确认后再处理。
as5w(如提示需要,请输入)
