0%

Safari阅读列表自动化:从书签到EPUB的完整工作流

Safari阅读列表自动化

我有一个习惯:看到值得阅读的文章,就随手加到Safari阅读列表。但问题是,几乎没时间去仔细看它们,日积月累,阅读列表里已经堆了70篇文章,像一个不断膨胀的”待阅读”黑洞,每次打开都充满愧疚感。

最近我终于决定做点什么。目标是:把这些文章导出成EPUB电子书,放到汉王电纸书上,这样至少有零碎时间时可以看看。原本以为是个简单任务,没想到一路走下来,踩了不少坑,但也因此摸索出了一套完整的自动化方案。

问题:从”稍后阅读”到”永不阅读”

Safari的阅读列表功能本身很方便:看到好文章,快捷键一按就加入了。但问题也在这里——太方便了,方便到我们只会添加,不会阅读。我的70篇文章就是这样来的:有Obsidian使用指南、AI/ML技术文章、开发工具文档、微信公众号文章,甚至还有PDF文档。

最初的想法很简单:导出成EPUB,放到电纸书里。但真正动手时发现几个问题:

  1. Safari没有原生导出功能:阅读列表只能手动复制链接
  2. 直接生成的EPUB只有链接:没有实际内容,还是要联网才能看
  3. 中文内容乱码:网页编码问题导致中文显示异常
  4. 邮件附件文件名错误:显示为”mime-attachment”而不是正确文件名

这些问题一个接一个,像多米诺骨牌一样倒下来。但解决每个问题的过程,也让整个方案逐渐变得完整和可靠。

方案:一步步构建自动化工作流

第一步:直接读取Safari书签

起初我想手动复制链接,但查了资料后,发现Safari的书签存储在~/Library/Safari/Bookmarks.plist这个文件里。这是一个二进制的plist文件,但可以用Python的plistlib库读取。

更好的是,GitHub上有个现成的工具safarireadinglist,专门用来读取Safari的阅读列表。安装后,几行代码就能导出:

1
2
3
4
from safarireadinglist import export

items = export.export_reading_list()
# 成功导出70个阅读列表项

但这里有个坑:macOS的TCC(透明度与同意)系统会阻止Terminal访问用户的Library文件夹。解决方案是:在”系统设置 → 隐私与安全性 → 完全磁盘访问”里,添加Terminal应用,然后完全退出Terminal(Command+Q)再重新打开。

这个权限问题卡了我很久,AppleScript也被禁止发送按键,最后只能直接修改plist文件。

第二步:抓取网页完整内容

导出链接只是第一步,真正难的是抓取每个网页的完整内容。我用了三个工具的组合:

  • requests:发送HTTP请求
  • readability-lxml:提取文章主要内容(去掉广告、导航栏等)
  • html2text:将HTML转换为Markdown

这里最大的坑是中文编码。有些网页声明是UTF-8,实际不是;有些根本不声明编码。我的解决方案是强制UTF-8,失败则用apparent_encoding

1
2
3
4
5
6
7
8
9
response.encoding = 'utf-8'
try:
response.text # 测试是否能解码
except UnicodeDecodeError:
response.encoding = response.apparent_encoding

# 确保返回UTF-8编码的字符串
title = str(title).encode('utf-8', errors='ignore').decode('utf-8')
content = str(content).encode('utf-8', errors='ignore').decode('utf-8')

另外,为避免被封IP,每次请求间隔1秒。70篇文章,大概2-3分钟。

第三步:生成EPUB电子书

有了Markdown内容,用Pandoc转换成EPUB就简单了:

1
pandoc input.md -o output.epub --toc --toc-depth=2 --epub-chapter-level=2

最终生成的EPUB有9.8MB,包含70篇文章的完整内容。65篇成功抓取,5篇失败(主要是GitHub、Google Drive等需要登录的页面)。

第四步:自动发送到邮箱

最后一步是自动发送邮件,这样我在办公室也能接收,或者转发给其他设备。我用了一个自己写的mail-skill,支持读取配置文件、发送附件。

这里又遇到一个坑:中文文件名在邮件客户端显示为”mime-attachment”。解决方案是使用RFC 2047编码,或者干脆用英文文件名(比如Safari_Reading_List_70_articles.epub),兼容性更好。

结果:一套完整的自动化方案

最终,我把整个流程封装成了一个Python脚本Safari-to-EPUB

1
python3 safari-to-epub-full.py

运行后会自动:

  1. 从Safari导出阅读列表(70篇文章)
  2. 抓取每个网页的完整内容(2-3分钟)
  3. 生成9.8MB的EPUB电子书
  4. 发送到我的邮箱

整个过程全自动,我只需要坐等邮件,然后把EPUB传到汉王电纸书上。

意外收获:清空阅读列表的解脱感

完成这一切后,我做了一件事:清空Safari阅读列表。

看着那70篇文章的列表变成0,有一种说不出的解脱感。它们不再是压在心头的”待阅读”负担,而是变成了实实在在的、可以随时翻阅的EPUB电子书。

更重要的是,这套自动化方案可以定期运行(比如每周一次),让阅读列表保持”轻盈”的状态。看到好文章,依然可以随手加入,不用担心再次堆积成山。

技术细节

如果你也想实现类似功能,这里是一些关键点:

依赖工具

  • safarireadinglist - 读取Safari书签
  • requests - HTTP请求
  • readability-lxml - 内容提取
  • html2text - HTML转Markdown
  • pandoc - 文档转换
  • mail-skill - 邮件发送

权限设置
Terminal需要完全磁盘访问权限才能读取~/Library/Safari/Bookmarks.plist

编码处理
所有内容强制UTF-8编码,确保中文正常显示

注意事项

  • 需要登录的页面(GitHub、Google Drive)无法抓取
  • 某些JavaScript渲染的页面可能抓取失败
  • 建议间隔1秒,避免被封IP

后续改进

目前这个方案只能在macOS上运行,因为它依赖Safari的plist文件。如果想跨平台,可以考虑:

  1. 支持浏览器导出的HTML书签文件
  2. 使用Pocket、Instapaper等在线服务的API
  3. 开发浏览器扩展,实时同步阅读列表

但就目前而言,这个方案已经很好地解决了我的问题。Safari阅读列表不再是黑洞,而是可以定期”收割”的内容源。

结语

回过头看,这个项目的起因很偶然,但解决过程中学到的技术(网页抓取、编码处理、自动化流程)都挺有价值的。更重要的是,它让我重新审视了自己的”稍后阅读”习惯——与其让文章在阅读列表里沉睡,不如主动把它们转化成可以随时阅读的形式。

毕竟,知识只有被阅读和思考,才有价值。


记录于 2026-02-04 08:00