跳到主内容

RSS 批量订阅抓取 - 免费几十个订阅源一次看完,重复自动合并(爬虫工具)

免费下载RSS 批量订阅抓取 v1.0.0
平台:Windows 10/11 (64位)大小:11.5 MB版本:v1.0.0更新:
下载地址 ▾
解压后双击即可运行,无需安装任何运行环境;只在你点击抓取时访问你填写的网址,其余数据都在本机处理。
关注几十个博客,一个个点开看更新太低效,也记不住哪条是新的

RSS 批量订阅抓取 运行界面

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

这个工具解决什么问题

关注了二三十个博客、专栏、资讯站的人,每天的动作基本是:把收藏夹里的订阅页挨个点开,从上往下扫一眼,判断「这条我是不是看过」。麻烦有两层。第一层是纯体力活——几十个页面点一遍,光是加载翻页就要十几分钟,很多源一天只更新一条,点开发现没变化,等于白跑。第二层更要命:就算把标题都扫了一遍,过两天再翻回来,根本记不住哪条是新的。人脑判断「这篇我是不是见过」非常不可靠,结果要么重复读旧文浪费时间,要么漏掉真正重要的新内容。装一个 RSS 阅读器当然能解决,但很多人不想为了看更新专门再养一个常驻软件、再注册一个账号,而且阅读器只显示未读,点开就消失,想回顾「这两天到底更新了什么」反而查不到。

  • 原来的做法:把十几个订阅页存进收藏夹,每天挨个点开扫一遍;看完靠脑子记「这条好像见过」;想知道这周更新了什么,只能凭印象猜
  • 用这个工具:订阅地址一次性填进列表,点一次「开始抓取」,所有源的更新按时间从新到旧排成一张表;跨源转载的同一篇文章自动合并成一条;上次标记过的默认不再显示,一眼只剩真正的新内容;点两下导出 CSV 存档
  • 省下来的:每天翻几十个页面、十几分钟的时间省掉,而且「哪条是新的」由程序判断,不再靠记忆,也不会漏看

技术实现

整个工具只用 Python 标准库(urllib + xml.etree.ElementTree + html.parser + email.utils + tkinter + json + csv),运行期不需要安装任何依赖,打包后是单个 exe,双击即用。技术上有四个刻意的取舍:第一,不引 feedparser 也不引 requests——RSS/Atom 的 XML 结构本身很简单,为它引入这两个库会让单文件 exe 体积翻几倍,而标准库完全够用;第二,解析器不按标签全名匹配,而是统一取「本地名」再比对,因为同一个概念在 RSS 2.0 / Atom / RDF 三种格式里的命名空间写法各不相同;第三,界面与核心逻辑彻底分离,核心层不 import 任何 GUI 库,这样可以脱离窗口跑全自动回归测试;第四,抓取前先读目标站点的 robots.txt,被明确禁止就跳过并说明原因,不做「先抓了再说」。

  • 三种订阅格式统一解析:按本地名匹配,不写死标签:RSS 世界里同一个概念在不同命名空间下标签名五花八门(pubDate / dc:date / published,description / encoded / summary),所以解析器先用 _lname() 取标签的「本地名」(去掉 {namespace} 前缀与 xxx: 前缀),再按本地名找子元素。三种格式分别走不同分支:RSS 2.0 从 channel/item 取;Atom 从 feed/entry 取,且链接必须从 <link href> 属性读、优先 rel="alternate"(否则会拿到指向自身的 rel="self");RDF(RSS 1.0) 的 item 与 channel 平级,按 channel/item 找会得到 0 条。
  • 畸形 XML 容错:未绑定命名空间前缀的源也能读:ElementTree 遇到未声明的前缀(内容里写了 dc:date 却没写 xmlns:dc)会直接抛 ParseError,而国内早期 RDF 源大量存在这种问题。解析前先用两条正则把裸 xxx: 前缀剥掉再试一次——因为解析只看本地名,剥掉不影响语义,却能让一批老源正常解析。两次都失败才报错,且报的是「订阅内容不是合法的 XML」这种中文提示,不是 Python 堆栈。
  • 编码嗅探:gb2312 / gbk 一律升级成 gb18030:判定顺序是 BOM → HTTP Content-Type 的 charset → XML 声明 / HTML meta → 试 UTF-8 → 试 GB18030 → 兜底 latin-1。关键是 gb2312 和 gbk 一律当成 gb18030 来解码:gb18030 是它们的超集,用它解码 gb2312 内容永远正确,反过来遇到生僻字就会失败。实测一份声明 charset=gb2312 的源,用 gb18030 解码中文标题完全正常。
  • 时间解析:RFC822 与 ISO8601 双通道 + 归一化:RSS 2.0 的 pubDate 是 RFC822 写法,交给 email.utils.parsedate_to_datetime(),它连 GMT、EST 这类时区缩写都能吃。Atom 的 published 是 ISO8601,而 datetime.fromisoformat() 在 Python 3.8–3.10 既不认 Z 结尾、也不认 +0800 这种不带冒号的偏移,所以先做两次正则归一化(Z → +00:00、+0800 → +08:00),并把超过 6 位小数的纳秒砍到微秒。全部转成 UTC 后再比较,显示时 astimezone() 转回本机时区。排序 key 是 (有没有时间, -时间戳, 原始下标),既让无时间的条目排最后,又避免 None 与 datetime 比较时抛 TypeError。
  • 跨源去重:按规范化链接合并,并记录「还被谁收录」:去重键是规范化链接(norm_link()):域名小写、去 fragment、去掉 utm_* / spm / from / fbclid 等跟踪参数、去末尾斜杠。同一篇文章被两个源转载时链接一致就会被合并,保留排序靠前(时间较新)的那份,并把另一处来源记进 also_in,界面上显示成「来源(+1)」。如果保留的那条缺摘要或缺时间,会用被合并那条补齐。没有链接的条目依次退回「源地址 + guid」「源地址 + 标题」。
  • 合规:抓之前先读 robots.txt,并做同域限速:check_robots() 解析 User-agent 分组(匹配我们 UA 名的分组与 User-agent: * 分组都算),收集 Allow / Disallow 后按最长前缀生效、同长时 Allow 优先,与主流搜索引擎一致。读不到 robots.txt 按允许处理(抓的是用户自己填的公开订阅地址),只有明确命中 Disallow 才拦下并给出原因。另有 MIN_HOST_INTERVAL = 1.2 秒的同域请求间隔,一次操作只处理用户列出的源、不做并发。已知局限:不解析 * 和 $ 通配符,当普通字符处理,属于宁可保守的取舍。
  • 订阅地址自动发现 + 后台线程不假死:用户常填博客首页而不是订阅地址,所以拿到内容先判断是 feed 还是网页(看根元素名,不看 Content-Type——很多站点把 feed 标成 text/html),是网页就解析 <link rel="alternate" type="application/rss+xml">,一个都没有再按 /feed、/rss.xml、/atom.xml 等常见路径依次试探(最多 6 个)。抓取跑在 threading.Thread 里,通过 queue.Queue 回传消息、主线程用 root.after(80) 轮询消费,tkinter 控件始终只在主线程被操作;未捕获异常挂在 root.report_callback_exception 与 sys.excepthook 上并弹窗——GUI 没有控制台,不弹窗用户只会以为点了没反应。

技术栈:Python 3.8+、零第三方依赖(纯标准库)、tkinter 图形界面、urllib + xml.etree 解析 RSS 2.0 / Atom / RDF、PyInstaller 单文件打包

已知局限:只解析静态内容,完全由 JavaScript 渲染出内容的站点抓不到。只支持 RSS 2.0 / Atom / RDF(RSS 1.0) 三种订阅格式,不处理 JSON Feed。robots 判定不支持 * 和 $ 通配符。不做并发抓取,源很多时(例如上百个)总耗时是线性累加的;没有内置定时任务,需要定期看就自己隔几天点一次。已读记录只存在本机,不跨设备同步。抓取速度取决于对方站点的响应速度,视机器与网络而定。

操作教程

  1. 双击打开程序
    解压后双击「RSS 批量订阅抓取.exe」,不需要安装 Python 或任何依赖。
    预期结果:出现主窗口,自上而下是①订阅源、②抓取选项、③执行按钮、④结果表格
  2. 添加订阅地址
    在①的输入框里粘贴订阅地址,点「添加」。可以直接粘博客首页地址,程序会自动去找它声明的订阅入口;地址多的时候用「从剪贴板导入」或「从文件导入」一次导入一堆(一行一个)。
    预期结果:地址出现在下面的列表里;列表会自动保存,下次打开程序还在
  3. 设置筛选条件(可选)
    在②里选择「只看最近」的天数、填关键词(多个词用空格分隔,全部命中才显示)、按需勾选「只显示新条目」和「抓取前检查 robots.txt」(默认都开)。
    预期结果:改动即时生效,结果表格里的行数跟着变化
  4. 点「开始抓取全部订阅源」
    程序在后台逐个抓取,进度条转圈、状态文字显示当前抓到第几个源,窗口不会卡死;中途可以点「停止」。
    预期结果:抓完后表格按时间从新到旧列出所有条目,底部汇总显示「共 N 个源,成功 X、失败 Y;抓到 M 条,去重后 K 条」
  5. 查看与打开条目
    双击任意一行会在浏览器里打开原文;选中多行后点「复制链接」或「复制标题」可以把内容带走。跨源重复的文章只会出现一条,来源列显示「原始来源(+1)」表示还有一处收录。
    预期结果:浏览器打开对应的文章页;复制的链接/标题已进剪贴板
  6. 导出存档、标记已读
    点「导出 CSV」把当前显示的条目存成表格(带 UTF-8 BOM,Excel 打开不乱码),或点「导出标题清单」只存标题。看完之后点「全部标记为已读」。
    预期结果:CSV 文件生成并可正常打开;标记后这些条目不再出现在「只看新条目」里

常见问题

Q:填博客首页可以吗,还是必须找 .xml 结尾的地址?A:填首页就行。程序会去读网页 <head> 里的 <link rel="alternate" type="application/rss+xml"> 自动找到订阅入口;如果一个都没声明,还会按 /feed、/rss、/rss.xml、/atom.xml、/index.xml 等常见路径依次试一遍,命中就用。
Q:为什么有的源抓不到?A:抓完会弹窗列出失败的源和具体原因,不会静默忽略。常见几种:站点根本没有 RSS(内容靠 JavaScript 渲染,抓不到静态 XML);被站点自己的 robots.txt 禁止(例如知乎的 /rss 就写了 Disallow: /,程序会直接跳过并提示,而不是硬抓);站点需要翻墙或已停止服务;地址拼错了。
Q:(+1)是什么意思?A:表示这篇文章除了当前显示的来源,还被另外 1 个订阅源收录,程序已经把它们合并成了一条。鼠标点一下看来源列就能看到主来源,导出 CSV 里「来源」列也是同一个值。
Q:「新条目」到底怎么判断的?为什么刷新之后都变成新的了?A:判断依据是链接(自动忽略 utm_source 这类跟踪参数),对照的是你本机的已读存档。新条目只有在你点过「全部标记为已读」之后才会变成已读,所以程序不会偷偷把红标抹掉。存档放在 %APPDATA%\RssBatchReader 目录。
Q:支持 Atom 和 RDF 格式吗?中文乱码怎么办?A:RSS 2.0、Atom、RDF(RSS 1.0)三种都支持,一个源是什么格式由程序自动识别。编码也会自动嗅探,gb2312 / gbk 一律按 gb18030 解码(超集,不会因生僻字失败),导出 CSV 带 UTF-8 BOM,Excel 打开中文不乱码。
Q:会不会给别人的网站造成压力?A:不会。同一个域名的两次请求之间至少有 1.2 秒间隔,不做并发,一次操作只抓你在列表里填的那几个源,不翻页、不递归。抓之前还会先读该站的 robots.txt,被明确禁止的路径直接跳过。
Q:一次填几十个源会不会很慢?A:程序是逐个抓的(刻意不做并发,避免给站点压力),几十个源通常一两分钟跑完,具体取决于每个站的响应速度。抓的过程中窗口不会卡死,可以随时点「停止」。
Q:数据会上传到你们服务器吗?A:不会。程序只在抓取时访问你自己填写的那些订阅地址,除此之外不向任何第三方发送数据;订阅列表和已读记录都只存在本机 %APPDATA%\RssBatchReader 目录下。

技术实现与后续维护

本工具由我们自行开发并持续维护,每次迭代都在本地跑过完整自测(106 项断言,含对本地测试服务的端到端抓取)。核心逻辑与界面彻底分离,抓取、解析、去重、过滤、导出都是可独立调用的纯函数,因此后续无论换界面还是换导出格式,改动都不会牵一发动全身。

技术构成:

  • src/rss_reader_gui.py —— 程序入口:tkinter 窗口布局、事件绑定、后台线程与消息队列调度、导出与存档按钮
  • src/rss_core.py —— 核心逻辑(不含任何界面代码):HTTP 访问与错误翻译、robots.txt 检查、三种订阅格式解析、时间解析、链接去重、条件过滤、已读存档、CSV 导出
  • src/sample_feeds.py —— 三种格式的样本订阅内容 + 本地 127.0.0.1 测试服务,供自测与「演示模式」复用
  • src/selftest.py —— 自测脚本:106 项断言,含对本地服务的真实 HTTP 端到端抓取

运行环境:

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

可扩展方向:

  • 定时自动抓取:配合 Windows 任务计划程序按间隔自动调起,或加一个常驻托盘模式
  • 抓取正文全文:顺着条目链接把正文抓下来并提取成纯文本 / Markdown 归档,而不只是 feed 自带的摘要
  • 导出格式扩展:除 CSV 与纯文本外,增加 Markdown 周报、Excel(自写 xlsx,保持零依赖)
  • 关键词规则升级:从「全部关键词都命中」升级成规则组,支持「或」「排除词」「只在标题里匹配」
  • OPML 导入导出:方便从其它阅读器批量迁移订阅列表(OPML 本身是 XML,标准库直接能写)
  • 去重策略参数化:目前按链接去重,可增加「按标题相似度」以覆盖链接不同的转载情况

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

需要其它功能?可以定制

这个工具只做一件事:关注几十个博客,一个个点开看更新太低效,也记不住哪条是新的。如果你的场景还需要别的处理,可以联系我们做二次开发,按你的实际数据格式和流程定制。

常见的定制需求:

  • 把抓到的更新自动汇总成一份 Markdown 周报,按来源分组、带日期和链接
  • 只跟踪特定几个栏目的更新(例如只看某站「技术」分类),支持多组关键词规则
  • 把结果直接写进你们内部的数据库或协作平台,而不是导出 CSV 手动导入
  • 给抓取加定时任务:每天早八点自动跑一次,把新增条目发到邮箱或群机器人
  • 对接内部 RSS 网关 / 私有源,支持需要携带固定请求头的订阅地址
  • 联系方式:邮箱/微信见站内「联系我们」页面,或在本文下方留言
  • 定制说明:请附上你的数据样例(脱敏即可)和期望结果,方便快速评估工作量
  • 交付形式:定制项目可交付可执行程序,按需一并交付源码与工程文档,支持长期维护

使用说明与免责声明

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

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

服务热线

加我微信

加我微信