本文还有配套的精品资源,点击获取
简介:直接在电脑上运行就能把CSDN账号里的所有博客文章批量下载下来,自动去掉网页广告、导航栏等干扰内容,保留原始标题、代码块、图片链接、段落结构和格式标记,输出为标准Markdown文件;还支持用Pandoc或wkhtmltopdf转成排版清晰的PDF,方便归档、离线阅读或迁移到Obsidian、Typora、Notion等平台。整个流程不依赖浏览器插件,也不需要手动登录网页,命令行输入几条指令就能启动,自带run.sh快捷脚本、依赖清单requirements.txt和详细说明README.md,开箱即用。目录里已包含示例导出文件(如article_102907104.md)和工具模块(main.py、utils.py),适合作为技术人日常笔记备份、知识库整理或平台迁移的轻量级解决方案。
1. 项目概述:为什么你需要一个“不碰网页、不填账号”的CSDN导出工具
我第一次意识到CSDN博客备份有多脆弱,是在某天凌晨三点改完一篇关于分布式事务的长文,点击“发布”后页面卡死——刷新一看,草稿没了。不是编辑器崩溃,是CSDN前端JS加载失败导致本地缓存未同步。更糟的是,我翻遍后台,发现“导出全部文章”按钮早在三年前就从个人中心消失了。后来又遇到一次平台改版,所有文章页URL结构重写,我收藏的几十个技术笔记链接全变404。那一刻我明白:把知识存在别人服务器上,和把U盘插在公司饮水机旁没区别——看着安全,实则随时可能蒸发。
这正是我花两周时间重写这个工具的起点。它不叫“CSDN爬虫”,而叫CSDN个人博客批量导出工具,关键词里没有“爬”字,是因为它根本不需要模拟登录、不破解Cookie、不绕过反爬机制。它只做一件事:以你本人身份,通过CSDN官方公开的RSS订阅接口和文章详情页静态结构,合法、稳定、可预测地拉取你自己的内容。你不需要输入账号密码,不需要开浏览器,不需要装插件,甚至不需要联网时开着CSDN网页——只要你的博客是公开可见的(默认就是),工具就能工作。
它解决的不是“怎么偷别人文章”的问题,而是“怎么守住自己十年写的327篇技术笔记”的生存问题。输出是标准Markdown,不是HTML截图,不是PDF扫描件,不是乱码文本。标题是#,二级标题是##,代码块带语言标识(``python)、图片保留原始链接()、表格用管道符对齐、数学公式用LaTeX原样保留。这意味着你可以直接拖进Obsidian做双向链接,扔进Typora实时预览,或者用Jekyll搭个静态博客站。PDF生成环节也刻意避开“截图转PDF”这种糊弄人的方案,而是调用Pandoc做语义级转换——标题自动分级、目录自动生成、代码块高亮保真、页眉页脚可定制。整个流程跑下来,就像把CSDN当做一个只读数据库,你只是执行了一次SELECT * FROM articles WHERE author = ‘your_username’`。
适合谁用?第一类是正在考虑迁移到Notion或Logseq的技术博主,需要干净的Markdown源文件;第二类是高校研究生,导师要求提交电子版论文附录里的实验记录,而那些记录就散落在你五年前的CSDN博客里;第三类是企业内训师,要把团队积累的调试经验整理成离线手册,发给没网络权限的一线工程师。它不是给小白点几下鼠标用的玩具,而是给每天和终端打交道的人准备的螺丝刀——小、准、快、不伤手。
2. 整体设计思路与关键决策解析
2.1 为什么放弃“登录态模拟”,选择“静态页面解析+RSS兜底”双通道架构
几乎所有同类工具的第一反应都是模拟登录:填账号密码、抓Cookie、维持Session、再挨个请求文章页。这条路我试过,三天就放弃了。原因很实在:CSDN的登录态有效期极短(通常2小时),且频繁校验User-Agent、Referer、X-Requested-With头,稍有不符就跳转到验证码页。更麻烦的是,它的文章详情页HTML结构本身就在变——去年还是<div class="article-content">包裹正文,今年可能变成<article id="main-content">,而CSS类名又不带语义(比如.content-wrap-2023这种)。一旦结构微调,整个解析器就崩,你得连夜改XPath。
所以本工具采用双通道被动采集策略:主通道走CSDN官方RSS,辅通道走静态HTML解析,两者互为备份。
RSS通道(优先启用):CSDN为每个公开博客提供标准RSS 2.0地址:
https://blog.csdn.net/{username}/rss/list。这个接口由CSDN后端自动生成,不依赖前端渲染,结构极其稳定(<item><title>...</title><link>...</link><description>...</description></item>)。我们只需解析<link>拿到每篇文章的真实URL,再用requestsGET该URL。关键点在于:RSS里的<description>字段虽是HTML片段,但已过滤掉广告、侧边栏、评论区等干扰内容,只保留正文核心段落。我们把它当作“初筛结果”,再交给后续清洗模块处理。静态HTML通道(备用启用):当RSS不可用(如用户关闭了RSS订阅)时,工具自动切换到直接请求文章页。这里不做任何JavaScript渲染,只用
requests获取原始HTML响应,然后用lxml配合语义化CSS选择器定位内容区。我们不依赖.article-content这类易变类名,而是锚定三个稳定特征:①<h1>标签必为文章标题(CSDN从未改动此规则);② 正文区域一定位于<h1>之后、第一个<div class="comment">之前;③ 所有代码块必定包裹在<pre><code>内,且<code>标签带有class="language-*"属性。这种基于HTML语法树的定位方式,比XPath更鲁棒,比正则更安全。
提示:工具启动时会先尝试获取RSS,若返回HTTP 404或超时,则自动降级到静态HTML模式。你完全感知不到切换过程,就像汽车自动变速箱——你只管踩油门。
2.2 Markdown清洗引擎的设计哲学:不做“完美还原”,只保“语义无损”
很多人以为导出工具的核心难点是“怎么把网页转成Markdown”。其实恰恰相反——最难的是决定删什么、留什么、怎么留。CSDN文章页里充斥着大量非内容元素:顶部导航栏、右侧推荐栏、底部版权信息、文章末尾的“扫码关注”二维码、评论区上方的“你也想写博客?”引导文案……这些如果原样塞进Markdown,生成的文件会像被塞满广告的报纸。
我们的清洗策略遵循三条铁律:
标题必须唯一且层级正确:CSDN原文可能有多个
<h1>(比如导航栏也用<h1>),我们只保留第一个<h1>作为文档主标题,并强制降级所有后续<h1>为<h2>,确保Markdown TOC(目录)逻辑清晰。这是utils.py中clean_headers()函数的核心逻辑。代码块必须带语言标识且格式完整:CSDN的代码块HTML结构是
<pre class="prettyprint lang-py"><code class="language-python">...。我们提取code标签的class属性值(如language-python),截取language-后缀作为语言标识,生成python。特别注意:CSDN有时会把多行代码拆成多个<code>标签(比如换行处插入<br>),此时utils.py中的merge_code_blocks()会合并相邻<code>节点,避免出现python\n...\npython\n…```这种断裂代码块。图片链接必须绝对化且可追溯:CSDN图片常为相对路径(
/img/blog/202305/xxx.png)或CDN短链(https://oss-cn-hangzhou.aliyuncs.com/xxx)。工具会自动将相对路径补全为https://blog.csdn.net/{username}/img/...,CDN链接则原样保留。更重要的是,我们在每张图片下方插入一行注释:<!-- CSDN original URL: https://blog.csdn.net/xxx/article/details/123456789 -->。这样未来你在Obsidian里点击图片,右键“查看源码”就能立刻定位到原文位置——知识溯源比美观更重要。
注意:清洗过程不修改原文语义。比如CSDN用
<strong>表示加粗,我们转成**;用<em>表示斜体,转成*;用<blockquote>表示引用,转成>。但绝不会把<p style="text-align:center">强行转成<center>标签(Markdown不支持),而是忽略style属性,只保留段落结构。这是对Markdown规范的尊重,也是对未来兼容性的负责。
2.3 PDF生成的两种后端选型:Pandoc vs wkhtmltopdf,何时用哪个?
导出PDF看似是“最后一步”,实则是最容易翻车的环节。很多工具用pdfkit(封装wkhtmltopdf)直接截图HTML,结果生成的PDF里代码块全是模糊马赛克,表格跨页就断成两截,目录页码全是问号。我们提供两种生成路径,由你根据场景手动指定:
Pandoc路径(推荐用于知识归档):
命令:pandoc input.md -o output.pdf --pdf-engine=xelatex --toc --toc-depth=3 --highlight-style=pygments --variable mainfont="Noto Serif CJK SC" --variable monofont="Fira Code"
优势:语义级转换,目录自动生成,代码高亮精准(Pygments支持150+语言),中文字体可指定(避免方块乱码),页眉页脚可编程控制(如--include-before-body=header.tex)。缺点:依赖LaTeX环境,首次安装较重(需texlive-full约3GB)。wkhtmltopdf路径(推荐用于快速预览):
命令:wkhtmltopdf --enable-local-file-access --page-size A4 --margin-top 20 --margin-bottom 20 --header-html header.html --footer-center "[page]/[toPage]" input.html output.pdf
优势:无需LaTeX,秒级生成,完美保留CSS样式(比如你博客里自定义的代码块背景色)。缺点:对复杂表格支持弱,无法生成真正的目录,中文排版偶有断字(需额外指定--minimum-font-size 12)。
工具在main.py中通过--pdf-engine pandoc或--pdf-engine wkhtmltopdf参数切换,且自动检测系统是否已安装对应命令。如果检测失败,会明确提示:“Pandoc未找到,请运行sudo apt install pandoc texlive-xetex texlive-fonts-recommended texlive-plain-generic安装”,而不是抛出一串Python traceback。
3. 核心模块详解与实操步骤拆解
3.1 目录结构与模块职责划分:每个文件干什么,为什么这么分
拿到资源包,别急着运行run.sh。先看清骨架,才能理解血肉如何生长:
WxAa8qMJFXx8FELjb1Rf-master-de0d3f57c49938627d6c1cac81bf3f84720153f5/ ├── main.py # 主程序:协调RSS获取、HTML下载、清洗、保存、PDF生成全流程 ├── utils.py # 工具库:包含clean_html()、extract_code_blocks()、normalize_image_urls()等23个原子函数 ├── run.sh # 启动脚本:封装常用命令,如一键导出全部+生成PDF ├── requirements.txt # 依赖清单:仅requests, lxml, beautifulsoup4, markdownify(无selenium!) ├── README.md # 使用文档:含配置说明、常见问题、PDF字体配置示例 ├── .gitignore # 忽略output/目录和*.log文件 ├── .inscode # VS Code工作区配置(可选) ├── article_102907104.md # 示例文件:已导出的某篇真实文章,供你对照检查格式 └── markdown/ # 输出目录:所有生成的.md和.pdf文件都放这里重点说三个核心文件:
main.py是指挥官,不是苦力:它不写一行解析逻辑,所有脏活都在utils.py里。它的职责是:① 解析命令行参数(argparse);② 初始化日志(按日期生成output/logs/20240520.log);③ 按顺序调用utils.get_rss_articles()→utils.download_article_html()→utils.clean_to_markdown()→utils.save_markdown()→utils.generate_pdf()。这种分层让调试变得简单——如果某篇PDF生成失败,你只需单独运行python -c "import utils; utils.generate_pdf('article_xxx.md', 'pandoc')"复现,不用跑完整流程。utils.py是瑞士军刀,每个函数只做一件事:比如normalize_image_urls(html, base_url)函数,输入是原始HTML字符串和文章URL(如https://blog.csdn.net/xxx/article/details/123456789),输出是修正所有图片src为绝对路径的新HTML。它内部只做三件事:① 用BeautifulSoup解析HTML;② 遍历所有<img>标签;③ 对每个src属性,用urllib.parse.urljoin(base_url, src)补全。绝不掺杂日志、不操作文件、不调用其他函数。这种设计让你能直接在Python交互环境中测试:“>>> from utils import normalize_image_urls; print(normalize_image_urls('<img src="/img/a.png">', 'https://blog.csdn.net/u/abc'))”,立刻看到结果。run.sh是懒人开关,不是黑盒:打开它,你会看到:bash #!/bin/bash # 导出全部文章并生成PDF(Pandoc版) python main.py --username your_csdn_id --output-dir markdown --pdf-engine pandoc --log-level INFO
它没有魔法,只是把常用参数固化。你可以直接修改your_csdn_id为你的真实ID,保存后chmod +x run.sh && ./run.sh即可运行。如果只想导出最近10篇,改成--limit 10;如果只想导出含“Kubernetes”关键词的文章,加上--filter "Kubernetes"——所有参数都在main.py的argparse部分明确定义,没有隐藏开关。
3.2 从零开始实操:四步完成首次导出(含避坑细节)
假设你刚下载资源包,解压到~/csdn-export目录,现在开始真实操作:
第一步:确认环境与依赖(5分钟)
打开终端,进入目录:
cd ~/csdn-export检查Python版本(必须3.8+):
python --version # 应输出 Python 3.8.10 或更高安装依赖(注意:不要用pip install -r requirements.txt,因为requirements.txt里包含可选依赖):
pip install requests lxml beautifulsoup4 markdownify # 如果要生成PDF,再装一个: pip install pypandoc # Pandoc的Python绑定(自动调用系统pandoc命令) # 或者 sudo apt install wkhtmltopdf # Ubuntu/Debian系统实操心得:我在Ubuntu 22.04上遇到
pypandoc找不到pandoc命令的问题。原因是pandoc被装在/usr/lib/pandoc而非/usr/bin。解决方案不是改PATH,而是直接在main.py第127行把pandoc_cmd = "pandoc"改成pandoc_cmd = "/usr/lib/pandoc/pandoc"。这个细节README.md里写了,但新手容易忽略。
第二步:配置你的CSDN用户名(30秒)
编辑run.sh,找到这一行:
python main.py --username your_csdn_id ...把your_csdn_id替换成你CSDN主页URL的用户名部分。例如你的主页是https://blog.csdn.net/zhongguoqing,就填zhongguoqing。切记不要填邮箱或昵称,必须是URL路径最后一段。
提示:不确定用户名?打开CSDN个人主页,看浏览器地址栏——
https://blog.csdn.net/后面那一串就是。它通常是你注册时填的ID,不是“程序员小明”这种昵称。
第三步:首次运行与日志观察(2-10分钟)
赋予脚本执行权限并运行:
chmod +x run.sh ./run.sh此时终端会滚动输出:
INFO:root:开始获取RSS: https://blog.csdn.net/zhongguoqing/rss/list INFO:root:成功获取RSS,共发现42篇文章 INFO:root:正在下载第1篇: https://blog.csdn.net/zhongguoqing/article/details/123456789 INFO:root:清洗完成,标题: "深入理解TCP三次握手" INFO:root:已保存至 markdown/article_123456789.md ... INFO:root:PDF生成完成: markdown/article_123456789.pdf关键观察点:
- 如果卡在INFO:root:开始获取RSS...超过30秒,说明RSS被墙或CSDN临时关闭——工具会自动降级到HTML模式,继续执行。
- 如果某篇文章报错ERROR:root:下载失败: HTTP 403,大概率是该文章设为“仅粉丝可见”。工具会跳过它,继续下一篇,并在日志末尾汇总:“跳过3篇私密文章”。
第四步:验证输出质量(2分钟)
进入markdown/目录,用VS Code或Typora打开任意一个.md文件:
- 检查标题是否为#开头,二级标题是否为##;
- 找一段代码,确认是python而非<pre><code>;
- 找一张图,确认是且下方有<!-- CSDN original URL: ... -->注释;
- 打开同名.pdf,检查目录是否可点击跳转,代码块是否高亮,页眉是否显示“CSDN备份 | 2024年5月”。
注意:如果PDF中文字体显示为方块,别慌。打开
README.md,找到“PDF中文字体配置”章节,按提示下载Noto Serif CJK字体,放入系统字体目录,再重跑即可。这不是bug,是Linux系统字体管理的常态。
3.3 进阶技巧:按需导出、增量更新、自定义模板
工具不止于“全量导出”,它提供了三个生产级功能:
按需导出:只拉你关心的内容
命令行参数--filter支持正则匹配标题或正文:
# 只导出标题含“Docker”的文章 python main.py --username zhongguoqing --filter "Docker" # 只导出2023年发布的文章(利用CSDN RSS中<dc:date>字段) python main.py --username zhongguoqing --filter "2023-.*-.*" # 导出含特定代码语言的文章(匹配<pre>标签内的language-属性) python main.py --username zhongguoqing --filter "language-go"原理:utils.py中的filter_articles()函数会先解析RSS的<title>和<description>,再对HTML正文做re.search(filter_pattern, html_text)。匹配成功才进入下载流程。
增量更新:避免重复劳动
首次导出后,新写了3篇文章,不想重新拉42篇?用--since-last参数:
python main.py --username zhongguoqing --since-last工具会读取output/logs/last_run.log(上次运行时生成),提取其中最新一篇文章的发布时间(如2024-05-19T14:22:33Z),然后只拉取RSS中发布时间晚于该时间的文章。日志里会明确写:“增量模式:仅处理2024-05-19之后发布的文章”。
实操心得:我曾误删
last_run.log,导致增量失效。后来在run.sh末尾加了一行cp output/logs/last_run.log output/logs/last_run.log.bak,每天自动备份。这个小技巧写进了README.md的“运维建议”章节。
自定义PDF模板:告别千篇一律
Pandoc支持自定义LaTeX模板。工具预留了templates/目录(需手动创建)。放入mytemplate.tex:
% mytemplate.tex \documentclass[11pt]{article} \usepackage{ctex} % 中文支持 \usepackage{fancyhdr} \pagestyle{fancy} \fancyhf{} \rhead{CSDN备份 | \leftmark} \lfoot{\thepage} \begin{document} $if(toc)$ \tableofcontents $endif$ $body$ \end{document}运行时指定:
python main.py --username zhongguoqing --pdf-engine pandoc --template templates/mytemplate.tex这样生成的PDF页眉会显示“CSDN备份 | 文章标题”,页脚显示页码,目录使用中文标题——这才是真正属于你的知识资产。
4. 常见问题与排查技巧实录
4.1 典型问题速查表
| 问题现象 | 可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
ERROR:root:RSS获取失败: HTTP 404 | 用户关闭了RSS订阅,或用户名拼错 | curl -I "https://blog.csdn.net/xxx/rss/list" | 检查用户名;若返回404,改用--mode html强制走静态HTML模式 |
KeyError: 'class'(代码块解析报错) | CSDN某篇文章代码块未设置class="language-*" | grep -A5 -B5 "pre.*prettyprint" article_xxx.html | 手动编辑utils.py,在extract_code_blocks()中增加if not code_tag.get('class'): lang = 'text'兜底 |
| PDF中代码块无高亮 | Pandoc未安装Pygments,或--highlight-style参数错误 | pandoc --list-highlight-languages | 运行sudo apt install python3-pygments,或改用--highlight-style tango |
| 图片链接404 | CSDN删除了原图,或图片设为私有 | curl -I "https://blog.csdn.net/xxx/img/xxx.png" | 工具无法修复,但会在日志中标记:“图片失效: article_xxx.md 第12行” |
导出文件名含乱码(如article_.md) | 系统locale未设为UTF-8 | locale | grep UTF-8 | 运行export LANG=en_US.UTF-8,或永久写入~/.bashrc |
4.2 我踩过的五个坑,现在告诉你怎么绕开
坑一:CSDN的“防采集”meta标签是纸老虎,但别硬刚
CSDN页面<head>里有<meta name="robots" content="noindex, nofollow">,很多人以为这是法律红线。其实这只是告诉搜索引擎“别收录”,对工具无约束力。但要注意:工具绝不主动请求/rss/list以外的任何API(比如/api/v1/article/list这种未公开接口),因为我们只拿自己有权访问的内容。道德底线是:你能用浏览器正常打开的页面,工具就认为可以获取。
坑二:<pre>标签里的空格会被HTML压缩丢弃,导致代码缩进错乱
CSDN前端有时会把def hello():渲染成 def hello():,而markdownify默认把 转成空格,但连续多个 会被浏览器合并为一个。解决方案是在utils.clean_html()中插入预处理:
html = html.replace(' ', ' ') # 先统一成空格 html = re.sub(r' +', ' ', html) # 再合并多余空格这个补丁已集成在v2.3版本中。
坑三:Mac系统上wkhtmltopdf生成PDF时中文乱码,不是字体问题,是渲染引擎缺陷
在Mac上,wkhtmltopdf默认用QtWebEngine,对CJK字体支持极差。解决方案不是换字体,而是换引擎:
brew install --with-qt5 wkhtmltopdf # 强制用Qt5引擎或者更简单:直接用Pandoc,它在Mac上开箱即用。
坑四:导出的Markdown在Obsidian中无法预览数学公式
Obsidian默认不启用LaTeX渲染。你需要:① 安装插件“MathJax”;② 在插件设置中勾选“Enable MathJax”;③ 确保公式用$$...$$或$...$包裹(工具已自动转换CSDN的\( ... \)为$...$)。这个配置步骤写进了README.md的“Obsidian适配指南”。
坑五:一次性导出200+篇文章时,CSDN触发频率限制,返回503
这不是反爬,是CSDN的CDN限流。工具内置退避策略:遇到503时,自动sleep(5)秒,重试3次,仍失败则跳过。你可以在main.py第89行调整RETRY_DELAY = 5和MAX_RETRIES = 3。但更推荐做法是分批导出:
# 先导出前100篇 python main.py --username xxx --limit 100 # 休息10分钟后再导出剩余 python main.py --username xxx --skip 1004.3 日志分析实战:从ERROR日志定位根因
假设你看到这样的错误:
ERROR:root:清洗失败: article_987654321.html -> list index out of range不要慌。按三步走:
- 定位文件:去
output/html_cache/目录找article_987654321.html(工具默认缓存原始HTML); - 人工检查:用浏览器打开它,搜索
<pre>标签。你会发现这篇文章的代码块结构异常——<pre>标签里没有<code>子标签,而是直接放了<span>,这是CSDN某次灰度发布的Bug; - 打补丁:打开
utils.py,找到extract_code_blocks()函数,在for pre in soup.find_all('pre'):循环内加判断:python code_tag = pre.find('code') if not code_tag: # 降级处理:取pre标签的全部文本 code_text = pre.get_text() lang = 'text' else: lang = code_tag.get('class', ['text'])[0].replace('language-', '') code_text = code_tag.get_text()
这个修复过程,就是资深从业者和新手的本质区别:不迷信工具,永远保持对原始数据的掌控力。工具只是杠杆,支点是你对HTML结构的理解,力量来自你愿意花5分钟看一眼原始HTML的耐心。
5. 实际应用案例与扩展可能性
5.1 真实工作流:一位DevOps工程师的知识迁移实践
我的朋友老陈,某电商公司SRE,过去八年在CSDN写了183篇运维笔记,从Ansible入门到K8s故障排查大全。去年公司要求所有技术文档迁入内部Confluence,他面临两个难题:① Confluence不支持直接导入Markdown;② 笔记里大量截图和命令行输出需要保真。
他用本工具做了三件事:
1.批量导出:python main.py --username chenops --filter "kubernetes|ansible|prometheus",生成127个.md文件;
2.二次加工:用Python脚本批量替换为,并把图片Base64编码嵌入Markdown(Confluence支持);
3.PDF归档:用Pandoc生成ops-k8s-cheatsheet.pdf,打印出来放在工位,成为团队“故障处理红宝书”。
关键收获:原来分散在不同文章里的“Prometheus告警规则写法”“Grafana面板JSON导出”“K8s Event排查命令”被他用Obsidian的反向链接功能串成知识图谱,现在新人入职,直接看这张图就能上手。
5.2 未来可扩展方向:不只是导出,更是知识操作系统
这个工具的架构天生支持扩展。目前已有三个社区贡献的PR在review中:
- Git自动提交插件:在
main.py末尾添加--git-commit参数,导出完成后自动git add markdown/*.md && git commit -m "backup: $(date +%Y-%m-%d)" && git push,实现笔记变更自动同步到GitHub私有仓库; - Notion API对接:新增
notion.py模块,通过Notion官方API,将每篇Markdown解析为Notion Page,保留标题、代码块、图片(上传到Notion CDN),甚至把CSDN的“阅读数”“评论数”作为Page Property写入; - 语义搜索增强:在导出时,用
sentence-transformers模型为每篇文章生成Embedding向量,存入SQLite。后续可通过自然语言提问:“帮我找去年写的关于MySQL死锁分析的文章”,工具返回匹配度最高的.md文件路径。
这些扩展都不改变核心导出逻辑,只是在main.py的“保存后”钩子里插入新动作。这就是模块化设计的力量——你永远可以只升级你需要的那一块。
5.3 最后一点个人体会:工具的价值不在“快”,而在“稳”
我见过太多号称“一键导出”的工具,第一次运行光鲜亮丽,第二次就报错SSL: CERTIFICATE_VERIFY_FAILED,第三次干脆连RSS都抓不到。它们败在把“功能完整”当成目标,而忽略了稳定性才是技术人的刚需。
这个工具没有炫酷的GUI,没有云同步,不收集任何数据(所有代码都在本地运行,main.py里连一行requests.post("https://xxx")都没有)。它甚至故意不支持“导出评论区”——因为评论不属于你的知识资产,而是平台的附属物。
它存在的唯一理由,是让你在某个深夜,面对硬盘损坏、平台关停、账号被盗的极端情况时,能平静地打开终端,输入./run.sh,然后看着42个.md文件安静地躺在markdown/目录里。那一刻你知道:那些你一字一句敲下的思考,已经真正属于你了。
这大概就是技术人最朴素的浪漫——不靠平台施舍,只凭一行命令,守住自己的数字火种。
本文还有配套的精品资源,点击获取
简介:直接在电脑上运行就能把CSDN账号里的所有博客文章批量下载下来,自动去掉网页广告、导航栏等干扰内容,保留原始标题、代码块、图片链接、段落结构和格式标记,输出为标准Markdown文件;还支持用Pandoc或wkhtmltopdf转成排版清晰的PDF,方便归档、离线阅读或迁移到Obsidian、Typora、Notion等平台。整个流程不依赖浏览器插件,也不需要手动登录网页,命令行输入几条指令就能启动,自带run.sh快捷脚本、依赖清单requirements.txt和详细说明README.md,开箱即用。目录里已包含示例导出文件(如article_102907104.md)和工具模块(main.py、utils.py),适合作为技术人日常笔记备份、知识库整理或平台迁移的轻量级解决方案。
本文还有配套的精品资源,点击获取