1hqa(如提示需要,请输入)
这个工具解决什么问题
做竞品资料、收集素材或者给方案配图时,最烦的一步是把网页上的图片弄到本地。一个详情页挂十几张图,一个图集页几十张,只能一张张右键「图片另存为」:点开菜单、挑目录、确认覆盖、再重命名,五十张图就要重复五十遍,最后还得自己按顺序编号。换成在线的「网页图片提取」也不省心——得把地址交给第三方站点,图多了限制张数,有的还要登录;内网页面或者带权限的资料,更不敢往外传。
- 原来的做法:右键逐张另存,或者把网页地址贴给第三方在线工具,图多了还要分批来
- 用这个工具:粘一次地址,列表里勾选后一次下载到本地文件夹,扩展名按真实格式自动纠正
- 省下来的:一个几十张图的页面,从反复点几十次变成点两下;图全部落在本机,不外传
技术实现
工程分成两层:src/webimg_core.py 是纯逻辑层,负责地址清洗、HTML 解析、robots 判定、抓取与文件命名,不引用任何界面库,可被自测脚本直接调用;src/app.py 是 tkinter 界面层,只做「取参数 → 调核心函数 → 显示结果」。界面上的耗时动作(抓页面、下载图片)全部丢给后台线程,结果用队列回传主线程刷新,所以点完按钮界面不会假死,进度条和状态文字能实时更新。所有 HTTP 请求都由自写的 fetch() 统一发出,异常一律翻译成中文原因,不让用户面对一串英文堆栈。
- 用 HTMLParser 而不是正则解析页面:属性顺序、单双引号、自闭合写法都会让正则出错,改用标准库 html.parser 的子类 HtmlImageParser,在 handle_starttag 里按标签分派。覆盖六类来源:img 的 src 与 8 个常见懒加载属性(data-src / data-original / data-lazy-src / data-actualsrc / data-echo 等)、img 与 source 的 srcset、video 的 poster、指向图片的 a 链接、内联 style 与 style 块里的 url(...)、link rel=icon。站点若用 <base href> 改写基准地址,后续地址会按它解析。脚本里的字符串常量故意不解析——误报率太高。
- 扩展名以文件头为准,不信 URL:sniff_image_ext() 读内容判断真实格式:JPEG 看 FF D8 FF,PNG 看 89 50 4E 47 0D 0A 1A 0A,GIF 看 GIF87a/GIF89a,WebP 看 RIFF+WEBP,AVIF 看 ISO-BMFF 的 ftyp 盒,SVG 看 <svg 开头。地址写 .jpg 而内容其实是 PNG 时,落盘文件会用 .png;内容是防盗链返回的 HTML 错误页时直接判定失败,不会写出一堆打不开的假图片。
- robots.txt 实现最长匹配 + 等长 Allow 优先:parse_robots() 只应用 User-agent: * 分组,规则按前缀匹配、命中最长的一条胜出,长度相同时 Allow 覆盖 Disallow。空值的 Disallow 行表示什么都不禁止,不能存成规则(否则 path.startswith("") 恒为真会把整站判成禁止抓取)。RobotsCache 按「主机:端口」缓存,页面级与图片级都检查——图片常挂在图床或 CDN 上,与页面不同域。同主机两次请求之间由 Throttle 保证至少间隔 0.15 秒。
- 抓取层不抛异常,错误全部说人话:fetch() 吞掉所有异常并返回 (data, info),info["error"] 是中文描述:403 提示可能开了防盗链,429 提示被限流,超时与域名解析失败分别给不同提示。URLError 里包的 reason 才是真原因,需要递归拆开判断。响应会按 Content-Encoding 解压 gzip,deflate 还兜了一层「raw deflate」(有些服务器少发 zlib 头)。User-Agent 必须纯 ASCII——HTTP 头按 RFC 只允许 latin-1,早期在 UA 里写中文会让每个请求都抛 UnicodeEncodeError。
- 文件名在 Windows 上安全,且同批不撞名:sanitize_filename() 处理非法字符、结尾点与空格、以及 CON/PRN/AUX/NUL/COM1-9/LPT1-9 这些保留设备名。make_filename() 优先用 URL 路径上的文件名(用户对照原页面最直观),没有可用名字时退化为 img_序号;传入 used 集合后同名自动追加 _2 / _3,落地前 unique_path() 再挡一次磁盘上已存在的文件。写文件用先写 .part 再 os.replace,中途失败不会留半个坏文件。
- 文本解码保留原编码,不乱加 BOM:decode_text() 按「响应头 charset → 页面 meta charset → UTF-8 → GB18030 → Latin-1」依次尝试。utf-8-sig 不被当作普通候选,只在内容开头真有 BOM 时才按 BOM 处理——把 utf-8-sig 混进候选表会导致给本来没有 BOM 的内容凭空加一个 BOM,白白改坏文件。
技术栈:Python 3.8+、tkinter 图形界面、标准库(零第三方依赖)、html.parser / urllib / threading、PyInstaller 单文件打包
已知局限:不启动无头浏览器,纯 JS 动态插入的图片抓不到;只解析页面内联的 style 与 style 块,外链 CSS 文件里的背景图不解析;不做 Cookie/登录态处理,需要登录才能看的页面拿不到;图片按 URL 去重,不做感知哈希比对。
操作教程
- 填页面地址
打开程序,把网页地址粘进「1. 页面地址」框里。一行一个,可以一次粘多个页面地址;不带 http:// 的也认(会自动补上)。
预期结果:输入框里出现你粘的地址,多行会按行拆开 - 点「解析图片」(快捷键 F5)
程序会抓取这些页面并列出里面所有图片地址,自动去重。表格里能看到文件名、来源类型(内容图 / 响应式 / 背景图 / 图片链接)。
预期结果:表格里出现图片清单,左上角显示「已选 N / N」,状态栏显示共发现多少张 - 按需勾选
单击表格最左侧那一列方框可以勾选或取消单张;也可以先用「全不选」再挑需要的。上面三个按钮是「全选 / 全不选 / 反选」。
预期结果:方框在勾与不勾之间切换,左上角已选数量跟着变 - 选保存目录
点「选择…」用系统对话框挑一个文件夹;下载完成后点「打开目录」可以直接在资源管理器里看结果。
预期结果:输入框显示完整目录路径 - 点「开始下载」(快捷键 F9)
程序按 4 个一组并发下载,进度条和「已下载/总数」会实时走。每一行的格式、大小、状态会随下载完成逐个刷新:已保存、已跳过(小于阈值)、robots禁止、失败。想中途停下就点「停止」。
预期结果:进度条走到满,状态栏显示「下载结束:成功 N 张,跳过 N 张,失败 N 张」 - 核对结果
对比表格里的文件名与磁盘上的文件。注意地址写 .jpg 而内容其实是 PNG 的图,列表里的文件名也会改成 .png,跟磁盘完全一致。
预期结果:磁盘上的文件数与「已保存」的行数一致
常见问题
技术实现与后续维护
本工具由我们自行开发并持续维护,每次迭代都在本机跑过完整自测。核心逻辑与界面是分开的两层:逻辑层不依赖任何界面库,改功能时可以脱离界面单独验证;抓取、解析、命名这些规则都有断言覆盖。下面说明它的技术构成与可扩展方向,方便你判断是否契合自己的场景。
技术构成:
src/app.py—— tkinter 界面层:控件布局、线程调度、队列回传、状态与错误展示src/webimg_core.py—— 核心逻辑层:网址清洗、HTML 图片提取、robots 解析与缓存、HTTP 抓取、格式识别、文件名生成、按主机限速src/demo_server.py—— 本地演示图库(纯标准库生成 PNG),供自测与运行截图使用tests/selftest.py—— 自测脚本:152 项断言,覆盖纯逻辑与本地服务端到端DOCS/开发文档.md—— 技术实现说明、编译打包方法、扩展点与维护约定
运行环境:
Windows 10/11 64 位,免安装运行环境,解压后双击 exe 即可。程序用 Python 3.8+ 与标准库开发,tkinter 为界面库,打包用 PyInstaller 的 --onefile --noconsole 生成单个 exe。正常运行不需要 .NET、不需要浏览器、不需要网络环境以外的任何组件。
可扩展方向:
- 解析外部 CSS 文件:把同站 .css 抓下来再抽 url(...),覆盖背景图写在样式表里的站点
- 接入无头浏览器:覆盖纯 JS 动态插入的图片(代价是交付体积明显变大)
- 图片去重:接入感知哈希,去掉同一张图的不同尺寸副本
- 分类归档:按来源页标题建子目录,或按尺寸规格分层存放
- 失败重试:把失败项记录成清单,下一次只补失败的那部分
本工具免费提供使用,但不对外分发源码。如果你需要在本工具基础上做功能调整、对接内部系统或长期维护,可以联系我们做二次开发,源码与工程文档可在定制合作中一并交付。
需要其它功能?可以定制
这个工具只做一件事:想把网页里的图片存下来,一张张右键另存太慢,图多了还要自己起名字。如果你的场景还需要别的处理,可以联系我们做二次开发,按你的实际数据格式和流程定制。
常见的定制需求:
- 下载后按图片尺寸自动分文件夹存放
- 对接内部对象存储或素材库,落盘同时入库
- 按固定周期自动跑一遍指定页面,新增图片自动收进归档
- 把解析结果导出成带来源页与尺寸的 CSV 清单
- 联系方式:邮箱/微信见站内「联系我们」页面,或在本文下方留言
- 定制说明:请附上你的数据样例(脱敏即可)和期望结果,方便快速评估工作量
- 交付形式:定制项目可交付可执行程序,按需一并交付源码与工程文档,支持长期维护
使用说明与免责声明
- 本工具仅用于采集公开可见或你自身拥有权限的数据。
- 请遵守目标网站的服务条款、robots 协议及《网络安全法》等相关法律法规。
- 请合理控制请求频率,不要对目标站点造成访问压力。
- 不得用于采集个人隐私、付费墙内容或任何受法律保护的非公开数据。
- 因使用不当造成的后果由使用者自行承担;本工具不做数据二次分发。
下载图片的版权归原作者或原站点所有,请在使用前确认你有相应的使用权;本工具只提供技术手段,不对下载内容的合规性负责。
1hqa(如提示需要,请输入)
