筑一道记忆的堤坝:用 Python 自动备份微信收藏与长图文并转存本地 Markdown

发布时间:2026/10/12 10:46:22

筑一道记忆的堤坝:用 Python 自动备份微信收藏与长图文并转存本地 Markdown 秋日的黄昏总是来得格外匆促。我坐在桌前想找回半年前在朋友圈偶然读到的一篇关于京都秋日庭院枯山水的长随笔。当时我随手点了“微信收藏”并满心以为这份美好的文字已经被安稳地妥善收纳。然而当我再次在收藏夹里点开那个链接时屏幕中央却只弹出一行冰冷无情的提示“该内容已被发布者删除无法查看”。那一瞬间的失落感就像在秋风中亲眼看着一片美丽的红叶被湍急的溪流瞬间卷走。在这个信息以毫秒流转的数字时代公网上的内容往往极其脆弱账号注销、服务器关停、链接失效、原作者误删……任何一个微小的变动都会让曾经触动过你内心的文字在互联网的荒原上灰飞烟灭。如果你真心喜欢一篇文章最好的爱护方式就是把它亲手搬运到自己的本地磁盘上配以干净整洁的 Markdown 格式与本地图片让它在完全断网的环境下也能随时为你翻开。为了筑起这道守护记忆的堤坝我们可以用 Python 编写一套小巧的“长图文离线转存备份器”。离线转存的核心难点防盗链与内容提纯要把一篇网页文章完好无损地保存为本地 Markdown通常需要跨越三道障碍第一图片防盗链拦截。许多内容平台尤其是微信生态对图片资源开启了严格的Referer防盗链检查。如果你直接在 Markdown 里引用原图 URL一旦脱离微信内置浏览器图片就会全面显示为破损的小叉号。我们必须在脚本抓取时伪造合规的请求头将图片完整下载到本地磁盘的相对目录中第二噪音节点剥离。网页中充斥着各类顶部横幅、底部广告引导关注、无意义的点赞按钮和样式脚本。我们需要精准提取文章的主体内容骨架剔除多余的 DOM 垃圾第三优雅排版重构。将提取到的文字自然转换为带有标题、作者、发布日期与本地图片链接的标准 Markdown以便能够无缝归纳进自己的知识库体系。核心实现从公网链接到本地纯净文档我们选用轻量级的网络请求库与文本提取工具。在终端中准备好运行环境pip install httpx beautifulsoup4 markdownify下面是经过反复实践打磨的核心转存脚本import os import re import hashlib from datetime import datetime from urllib.parse import urlparse import httpx from bs4 import BeautifulSoup from markdownify import markdownify as md # 本地归档根目录与图片存放目录 ARCHIVE_DIR os.path.expanduser(~/Documents/PersonalArchive) IMAGES_DIR os.path.join(ARCHIVE_DIR, assets) def sanitize_title(title: str) - str: 清理文件名中的非法字符 clean re.sub(r[\\/:*?|], _, title) return .join(clean.split()).strip() def download_image(img_url: str, referer_url: str) - str: 下载图片至本地并突破防盗链返回相对路径 os.makedirs(IMAGES_DIR, exist_okTrue) # 用 URL 的 MD5 命名天然防止重复下载 img_hash hashlib.md5(img_url.encode(utf-8)).hexdigest() img_ext .jpg # 默认回退格式 # 尝试从 URL 推测实际格式 if wx_fmtpng in img_url or img_url.endswith(.png): img_ext .png elif wx_fmtwebp in img_url or img_url.endswith(.webp): img_ext .webp local_filename f{img_hash}{img_ext} local_path os.path.join(IMAGES_DIR, local_filename) rel_path fassets/{local_filename} if os.path.exists(local_path): return rel_path headers { User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36, Referer: referer_url # 破解防盗链的核心 } try: with httpx.Client(timeout15.0) as client: resp client.get(img_url, headersheaders) if resp.status_code 200: with open(local_path, wb) as f: f.write(resp.content) return rel_path except Exception as e: print(f图片下载异常: {img_url}, 原因: {e}) return img_url # 降级返回原地址 def backup_article(target_url: str, category_tag: str 秋日阅读): 抓取长图文并重构为温润的本地 Markdown headers { User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) } with httpx.Client(timeout20.0, follow_redirectsTrue) as client: resp client.get(target_url, headersheaders) resp.raise_for_status() html resp.text soup BeautifulSoup(html, html.parser) # 1. 提取文章标题与元数据 title_el soup.select_one(h1.rich_media_title) or soup.select_one(h1) raw_title title_el.get_text(stripTrue) if title_el else 无标题归档随笔 title sanitize_title(raw_title) author_el soup.select_one(#js_name) or soup.select_one(.author) author author_el.get_text(stripTrue) if author_el else 未知作者 # 2. 定位正文容器并清洗 content_el soup.select_one(#js_content) or soup.select_one(.rich_media_content) or soup.select_one(article) if not content_el: print(未定位到有效正文容器跳过。) return # 3. 处理图片替换>
延伸阅读

更多相关文章

2026/10/12 10:46:22

安全帽检测在RK3588上的部署实践与边缘AI架构选型

在拿到“安全帽检测放 RK3588 上做”这个选题时,我第一时间想到的不是模型精度,也不是 NPU 算力,而是去年夏天在某工地现场蹲了一周之后积累下来的一堆问题。那会儿我们用的还是 x86 小主机加 GPU 的方案,机器放在配电箱旁边&…

2026/10/12 12:06:45

群论统一视角下的位置编码:GRAPE框架解析与复现

1. 从"位置"这件事说起:为什么Transformer需要位置编码如果你接触过Transformer架构,一定绕不开一个核心矛盾:自注意力机制本身是置换不变的。换句话说,你把输入序列里的词打乱顺序,注意力算出来的结果只是跟…

2026/10/12 12:06:45

Python采集腾讯新闻实例

前言 拿一个真实门户站当例子来练手,是很有价值的,因为门户站会把你在练习站上遇不到的问题一次性摆到面前:列表页和详情页要分两步抓、页面里混着广告和推荐位、内容可能由 JavaScript 渲染、站点还会不时改版。但正因为是真实站点&#xff…

2026/10/12 12:06:45

单级式光伏并网仿真:MPPT与并网控制耦合及参数整定全攻略

1. 为什么执意选单级式拓扑:省掉一级变换带来的控制难题单级式光伏并网系统,简单说就是光伏阵列直接接一台逆变器,再通过滤波器并入电网,中间没有DC-DC升压环节。相比两级式拓扑(前级Boost调压、后级逆变并网&#xff…

2026/10/12 12:06:45

PYNQ PS定时器中断实战:从UIO到内核模块的微秒级调度

1. 从裸机到异构:为什么PS定时器中断值得单独拎出来讲做过嵌入式开发的人都有一个共识:中断这东西,入门容易精通难。尤其在异构平台上,比如带有ARM处理器和可编程逻辑的SoC架构,中断的分配、路由、响应路径比传统单片机…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑