目录
- 思路
- Usage
- END
CSDN 真是💊,经常性的不能访问,而且如果不用广告插件的话页面简直不能看,前段时间又挂了,发了个帖子吐槽了一下:CSDN 博客又挂了。。。 - V2EX。本来也考虑过自己做个,看了好久,但是由于自己对网站相关的不太懂,看着教程又复杂,就没弄了。CSDN 这次挂真让我铁了心弄自己的网站,然后用了一个下午搭起来了,随后又陆陆续续改了改主题配置之类的,弄这个还是我最近第一次一两点才睡,后来还感冒了 😞
内容为王,站搭起来了,就需要内容来充实。但是我的文章都在 CSDN 上,手动一篇一篇导过来太慢,而且 hexo 的文章需要在头部添加 Front-matter,所以这样一来工作量就更大了,所以考虑用 Python 把文章都爬过来,然后统一添加 Front-matter。
完整程序源码在 secsilm/csdn2md: Export csdn blogs to markdown files.。
Note:你的文章必须是使用 markdown 写的,不然无法使用本文方法导出。
思路
对于单篇文章,CSDN 有导出为 markdown 的功能,如下图:
但是这样费时费力,所以我们需要找到当我们点击编辑
按钮时,网页向服务器发送的请求地址,这样我们就可以直接获取到博客内容,也就可以重新写入到 markdown 文件了。
我们在文章页按F12
调出开发者工具,切换到Network
选项卡,然后点击编辑
,可以看到如下几个请求:
webspeeds
无关,那么剩下两个,从名字可以很快看出来我们需要的是第二个:
1
| http://write.blog.csdn.net/mdeditor/getArticle?id=53418159&username=u010099080
|
可以看到需要两个参数:id
和username
,id
就是文章 id,这个很好获取,可以在文章地址中找到。username
则是你的用户名,也可以在你的博客地址中找到。
下面我们看下请求头:
可以看到其实也没啥特别的,其中Cookie
是一会儿我们需要的,你可以将此复制到一个 txt 文件(假设名字叫cookies.txt
)中以备后用。由于 cookie 字符串是存在一个文件中的,所以需要一个函数来解析成dict
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def read_and_parse_cookies(cookie_file): """读取并解析 cookies。
Args: cookie_file: 含有 cookies 字符串的 txt 文件名
Returns: 一个字典形式的 cookies """ with open(cookie_file, 'r') as f: cookies_str = f.readline() cookies_dict = {} for item in cookies_str.split(";"): k, v = item.split("=", maxsplit=1) cookies_dict[k.strip()] = v.strip() return cookies_dict
|
那么现在我们就可以使用requests
来发起请求:
1 2 3 4 5 6 7
| base_url = 'http://write.blog.csdn.net/mdeditor/getArticle' params = { 'id': article_id, 'username': username }
r = requests.get(base_url, params=params, cookies=cookies)
|
再从开发者工具看下请求返回值:
基本上囊括了一篇文章的所有信息了,而我们只需要里面的markdowncontent
、title
和create
。而且返回的数据是 json 格式,我们可以用json.loads()
来解析成dict
格式,方便我们写入文件:
1
| data = json.loads(r.text, strict=False)
|
最后由于我是要导入到 hexo 站点中,所以需要加 Front-matter,所以在获取到文章内容后,需要先把定义好的 Front-matter 加到文章内容里,一起写入文件:
1 2 3 4 5 6 7 8 9 10 11 12
| if hexo: hexo_str = '---\ntitle: {title}\ndate: {date}\ntags:\n---\n\n'.format( title=title, date=data['data']['create'])
forbidden = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
if any([c in repr(title) for c in forbidden]): with open(os.path.join(md_dir, article_id + '.md'), 'w', encoding='utf8') as f: f.write(hexo_str + data['data']['markdowncontent']) else: with open(os.path.join(md_dir, title + '.md'), 'w', encoding='utf8') as f: f.write(hexo_str + data['data']['markdowncontent'])
|
至于如何通过文章列表获取文章 id,这个比较简单,我就不赘述了,大家可以直接看源码。
Usage
程序使用fire
来从命令行接收参数,如何使用fire
请参考 Python 自动生成命令行工具 - fire 简介 · Lee’s Space Station。我们可以使用如下命令来查看帮助:
1
| python csdn2md.py -- --help
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Type: function String form: <function to_md_files at 0x000001CACC8C5E18> File: d:\chromedownload\mdfiles\csdn2md.py Line: 47 Docstring: 导出为 Markdown 文件。
Args: total_pages: 博客文章在摘要模式下的总页数 filename: 含有 cookies 字符串的 txt 文件名 start: 从 start 页开始导出 (default: {1}) stop: 到 stop 页停止 (default: {None}) hexo: 是否添加 hexo 文章头部字符串(default: {True}) md_dir: md 文件导出目录,默认为当前目录(default: .)
Usage: csdn2md.py USERNAME TOTAL_PAGES COOKIE_FILE [START] [STOP] [HEXO] [MD_DIR] csdn2md.py --username USERNAME --total-pages TOTAL_PAGES --cookie-file COOKIE_FILE [--start START] [--stop STOP] [--hexo HEXO] [--md-dir MD_DIR]
|
从帮助可以看出,你需要提供用户名username
、博客总页数total-pages
和 cookie 文件名cookie-file
,可选参数为start
、stop
(默认为None
,即一直到博客文章最后一页)、hexo
和md-dir
。
例如,你需要导出博客的第一页文章到当前目录下的mdfiles
目录,你的博客总页数为3
,那么只需要执行如下命令:
1
| python csdn2md.py --username u010099080 --total-pages 3 --cookie-file cookies.txt --stop 1 --md-dir mdfiles
|
控制台输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 2017-12-25 11:54:08 INFO: Page 1 2017-12-25 11:54:08 INFO: Exporting 【TensorFlow】理解 Estimators 和 Datasets ... 2017-12-25 11:54:08 INFO: Exporting Windows 10 资源管理器黑色风格 ... 2017-12-25 11:54:09 INFO: Exporting 梯度下降优化算法概述 ... 2017-12-25 11:54:09 INFO: Exporting 使用集成学习提升机器学习算法性能 ... 2017-12-25 11:54:09 INFO: Exporting 【TensorFlow | TensorBoard】理解 TensorBoard ... 2017-12-25 11:54:09 INFO: Exporting 【Python】Numpy 中的 shuffle VS permutation ... 2017-12-25 11:54:09 INFO: Exporting 【TensorFlow】DNNRegressor 的简单使用 ... 2017-12-25 11:54:09 INFO: Exporting XGBoost 在 Windows 10 和 Ubuntu 上的安装 ... 2017-12-25 11:54:10 INFO: Exporting 【Python】自动生成命令行工具 - fire 简介 ... 2017-12-25 11:54:10 INFO: Exporting 奇异值分解 SVD 的数学解释 ... 2017-12-25 11:54:10 INFO: Exporting 【Python】统计字符串中英文、空格、数字、标点个数 ... 2017-12-25 11:54:10 INFO: Exporting 【TensorFlow】TensorFlow 的卷积神经网络 CNN - TensorBoard版 ... 2017-12-25 11:54:10 INFO: Exporting 使用 tree 命令格式化输出目录结构 ... 2017-12-25 11:54:11 INFO: Exporting VSCode Markdown PDF 导出成PDF报 phantomjs binary does not exist 错误的解决办法 ... 2017-12-25 11:54:11 INFO: Exporting 【Python】numpy 中的 copy 问题详解 ... 2017-12-25 11:54:11 INFO: Done!
|
mdfiles
文件夹:
END
当然,导出的文件中 Front-matter 中的 tags
还是需要自己添加,因为我想自己再重新加标签而不是使用原来的标签,如果你想使用原来的标签,那么只需把请求返回 json 数据中的categories
提取出来加进去即可。
Merry Christmas! 😄