Python 博客园备份迁移脚本

鉴于有些小伙伴在寻找博客园迁移到个人博客的方案,本人针对博客园实现了一个自动备份脚本,可以快速将博客园中自己的文章备份成Markdown格式的独立文件,备份后的md文件可以直接放入到hexo博客中,快速生成自己的站点,而不需要自己逐篇文章迁移,提高了备份文章的效率。

首先第一步将博客园主题替换为 codinglife默认主题,第二步登录到自己的博客园后台,然后选择 博客备份,备份所有的随笔文章,如下所示:

备份出来以后将其命名为 backup.xml,然后新建一个 main.py脚本,以及一个 blog目录,代码实现的原理是,解析xml格式并依次提取出文档内容,然后分别保存为markdown文件。

Python 博客园备份迁移脚本

转存文章到MarkDown格式: 写入备份脚本,代码如下所示,运行后即可自动转存文件到 blog目录下,当运行结束后备份也就结束了。

powerby: LyShark
blog: www.cnblogs.com/lyshark
from bs4 import BeautifulSoup
import requests, os,re

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) By LyShark CnblogsBlog Backup Script"}

获取文章,并转成markdown
blog: www.lyshark.com
def GetMarkDown(xml_file):
    con = open(xml_file, 'r', encoding='utf8').read()
    # 每篇文章都在  标签里
    items = re.findall(".*?", con, re.I | re.M | re.S)
    ele2 = ['(.+?)', '(.+?)', '(.+?)']
    # md_name = xml_file.split('.xml')[0] + '.md'
    for item in items:
        try:
            title = re.findall(ele2[0], item, re.I | re.S | re.M)[0]
            link = re.findall(ele2[1], item, re.I | re.S | re.M)[0]
            des = re.findall(ele2[2], item, re.I | re.S | re.M)[0]
            des = re.findall('', des, re.I | re.S | re.M)[0]  # CDATA 里面放的是文章的内容
            des = des.replace('~~~', "")
            lines = des.split('\n')
            with open("./blog/" + title.replace("/","") + ".md", mode='w+', encoding='utf8') as f:
                f.write("---\n")
                f.write("title: '{}'\n".format(title.replace("##","").replace("###","").replace("-","").replace("*","").replace("","").replace(":","").replace(":","").replace(" ","").replace(" ","").replace("","")))
                f.write("copyright: true\n")

                setdate = "2018-12-27 00:00:00"
                try:
                    # 读取时间
                    response = requests.get(url=link, headers=header)
                    print("读取状态: {}".format(response.status_code))

                    if response.status_code == 200:
                        bs = BeautifulSoup(response.text, "html.parser")
                        ret = bs.select('span[id="post-date"]')[0]
                        setdate = str(ret.text)
                        pass
                    else:
                        f.write("date: '2018-12-27 00:00:00'\n")
                except Exception:
                    f.write("date: '2018-12-27 00:00:00'\n")
                    pass

                f.write("date: '{}'\n".format(setdate))

                # description检测
                description_check = lines[0].replace("##","").replace("###","").replace("-","").replace("*","").replace("","").replace(":","").replace(":","").replace(" ","").replace(" ","")
                if description_check == "":
                    f.write("description: '{}'\n".format("该文章暂无概述"))
                elif description_check == "C":
                    f.write("description: '{}'\n".format("该文章暂无概述"))
                elif description_check == "":
                    f.write("description: '{}'\n".format("该文章暂无概述"))
                else:
                    f.write("description: '{}'\n".format(description_check))

                print("[*] 时间: {} --> 标题: {}".format(setdate, title))
                f.write("tags: '{}'\n".format("tags10245"))
                f.write("categories: '{}'\n".format("categories10245"))
                f.write("---\n\n")
                f.write('%s' %des)
                f.close()
        except Exception:
            pass

if __name__ == "__main__":
    GetMarkDown("backup.xml")

备份后的效果如下所示:

Python 博客园备份迁移脚本

打开Markdown格式看一下,此处的标签和分类使用了一个别名,在备份下来以后,你可以逐个区域进行替换,将其替换成自己需要的分类类型即可。

Python 博客园备份迁移脚本

转存图片到本地: 接着就是继续循环将博客中所有图片备份下来,同样新建一个 image文件夹,并运行如下代码实现备份。

powerby: LyShark
blog: www.cnblogs.com/lyshark
from bs4 import BeautifulSoup
import requests, os,re

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) By LyShark CnblogsBlog Backup Script"}

从备份XML中找到URL
def GetURL(xml_file):
    blog_url = []
    con = open(xml_file, 'r', encoding='utf8').read()
    items = re.findall(".*?", con, re.I | re.M | re.S)
    ele2 = ['(.+?)', '(.+?)', '(.+?)']
    for item in items:
        try:
            title = re.findall(ele2[0], item, re.I | re.S | re.M)[0]
            link = re.findall(ele2[1], item, re.I | re.S | re.M)[0]
            print("标题: {} --> URL: {} ".format(title,link))
            blog_url.append(link)
        except Exception:
            pass

    return blog_url

下载所有图片
blog: www.lyshark.com
def DownloadURLPicture(url):
    params = {"encode": "utf-8"}
    response = requests.get(url=url, params=params, headers=header)
    # print("网页编码方式: {} -> {}".format(response.encoding,response.apparent_encoding))
    context = response.text.encode(response.encoding).decode(response.apparent_encoding, "ignore")
    try:
        bs = BeautifulSoup(context, "html.parser")
        ret = bs.select('div[id="cnblogs_post_body"] p img')
        for item in ret:
            try:
                img_src_path = item.get("src")
                img_src_name = img_src_path.split("/")[-1]
                print("[+] 下载图片: {} ".format(img_src_name))
                img_download = requests.get(url=img_src_path, headers=header, stream=True)
                with open("./image/" + img_src_name, "wb") as fp:
                    for chunk in img_download.iter_content(chunk_size=1024):
                        fp.write(chunk)
            except Exception:
                print("下载图片失败: {}".format(img_src_name))
                pass
    except Exception:
        pass

if __name__ == "__main__":
    url = GetURL("backup.xml")
    for u in url:
        DownloadURLPicture(u)

备份后的效果如下:

Python 博客园备份迁移脚本

替换文章内的图片链接地址,可以使用编辑器,启用正则 https://img2020.cnblogs.com/blog/(.*?)/(.*?)/批量替换。

Python 博客园备份迁移脚本

当把博客备份下来以后你就可以把这些文章拷贝到 hexo博客 _post目录下面,然后 hexo命令快速渲染生成博客园的镜像站点,这样也算是增加双保险了。

对过滤器的进一步优化,使之可以直接过滤出特定的标题,只需要稍微修改一下代码即可,如下代码可实现过滤特定关键词的文章。

powerby: LyShark
blog: www.cnblogs.com/lyshark
from bs4 import BeautifulSoup
import requests, os,re

header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) By LyShark CnblogsBlog Backup Script"}

获取文章,并转成markdown
blog: www.lyshark.com
def GetMarkDown(xml_file,grep_title,tags):
    con = open(xml_file, 'r', encoding='utf8').read()
    # 每篇文章都在  标签里
    items = re.findall(".*?", con, re.I | re.M | re.S)
    ele2 = ['(.+?)', '(.+?)', '(.+?)']
    # md_name = xml_file.split('.xml')[0] + '.md'
    for item in items:
        try:
            title = re.findall(ele2[0], item, re.I | re.S | re.M)[0]
            link = re.findall(ele2[1], item, re.I | re.S | re.M)[0]
            des = re.findall(ele2[2], item, re.I | re.S | re.M)[0]
            des = re.findall('', des, re.I | re.S | re.M)[0]  # CDATA 里面放的是文章的内容
            des = des.replace('~~~', "")
            lines = des.split('\n')

            # 判断是否存在:或者是空格
            if title.find(":") != -1 or title.find(":") != -1 or title.find(" ") != -1:

                # 过滤特定关键字
                if title.find(grep_title) != -1:
                    local_tags = ""
                    if local_tags == "":
                        local_tags = title.split(":")[0]
                    if local_tags == "":
                        local_tags = title.split(":")[0]
                    if local_tags == "":
                        local_tags = title.split(" ")[0]
                    if local_tags == "":
                        local_tags = title.split(" ")[0]
                    # print("[只过滤] 标签: {}".format(local_tags))

                    # 开始转存
                    with open("./blog/" + title.replace("/", "") + ".md", mode='w+', encoding='utf8') as f:
                        f.write("---\n")
                        f.write("title: '{}'\n".format(title.replace("##", "").replace("###", "").replace("-", "").replace("*", "").replace("","").replace(":", ":").replace(":", ":").replace(" ", "").replace(" ", "").replace("", "")))
                        f.write("copyright: true\n")

                        setdate = "2000-01-01 00:00:00"
                        try:
                            # 读取时间
                            response = requests.get(url=link, headers=header)

                            if response.status_code == 200:
                                bs = BeautifulSoup(response.text, "html.parser")
                                ret = bs.select('span[id="post-date"]')[0]
                                setdate = str(ret.text)
                                pass
                            else:
                                f.write("date: '2000-01-01 00:00:00'\n")
                        except Exception:
                            f.write("date: '2000-01-01 00:00:00'\n")
                            pass

                        f.write("date: '{}'\n".format(setdate))

                        # description 检测描述信息的输出
                        description_check = lines[0].replace("##", "").replace("###", "").replace("-", "").replace("*","").replace("", "").replace(":", "").replace(":", "").replace(" ", "").replace(" ", "")
                        if description_check == "":
                            f.write("description: '{}'\n".format("该文章暂无概述,自动增加注释"))
                        elif description_check == "C":
                            f.write("description: '{}'\n".format("该文章暂无概述,自动增加注释"))
                        elif description_check == "":
                            f.write("description: '{}'\n".format("该文章暂无概述,自动增加注释"))
                        elif description_check == "BASH":
                            f.write("description: '{}'\n".format("该文章暂无概述,自动增加注释"))
                        elif description_check == "":
                            f.write("description: '{}'\n".format("该文章暂无概述,自动增加注释"))
                        else:
                            f.write("description: '{}'\n".format(description_check))

                        print("[*] 状态: {} --> 时间: {} --> 标题: {}".format(response.status_code, setdate, title))

                        # 开始打标签
                        f.write("tags: '{}'\n".format(tags))
                        f.write("categories: '{}'\n".format(tags))
                        # print("[*] 打标签")
                        f.write("---\n\n")
                        f.write('%s' % des)
                        f.close()
        except Exception:
            pass

从备份XML中找到URL
def GetURL(xml_file,grep_title):
    blog_url = []
    con = open(xml_file, 'r', encoding='utf8').read()
    items = re.findall(".*?", con, re.I | re.M | re.S)
    ele2 = ['(.+?)', '(.+?)', '(.+?)']
    for item in items:
        try:
            title = re.findall(ele2[0], item, re.I | re.S | re.M)[0]
            link = re.findall(ele2[1], item, re.I | re.S | re.M)[0]
            # print("标题: {} --> URL: {} ".format(title,link))

            # 判断是否存在:或者是空格
            if title.find(":") != -1 or title.find(":") != -1 or title.find(" ") != -1:

                # 过滤特定关键字
                if title.find(grep_title) != -1:
                    # print("[只过滤] 标签: {}".format(grep_title))
                    blog_url.append([title,link])

        except Exception:
            pass

    return blog_url

下载所有图片
blog: www.lyshark.com
def DownloadURLPicture(title,url):
    params = {"encode": "utf-8"}
    response = requests.get(url=url, params=params, headers=header)
    # print("网页编码方式: {} -> {}".format(response.encoding,response.apparent_encoding))
    context = response.text.encode(response.encoding).decode(response.apparent_encoding, "ignore")
    try:
        print("当前文章: {} | URL: {}".format(title,url))

        bs = BeautifulSoup(context, "html.parser")
        ret = bs.select('div[id="cnblogs_post_body"] p img')
        for item in ret:
            try:
                img_src_path = item.get("src")
                img_src_name = img_src_path.split("/")[-1]
                print("[+] Down --> {} ".format(img_src_name))
                img_download = requests.get(url=img_src_path, headers=header, stream=True)
                with open("./image/" + img_src_name, "wb") as fp:
                    for chunk in img_download.iter_content(chunk_size=1024):
                        fp.write(chunk)
            except Exception:
                print("[-] DownError: {}".format(img_src_name))
                pass
    except Exception:
        pass

if __name__ == "__main__":
    backup_title = "驱动开发:"
    tags = "Windows 内核安全编程技术实践"
    backup_file = "./backup.xml"

    GetMarkDown(backup_file,backup_title, tags)

    for u in GetURL(backup_file,backup_title):
        DownloadURLPicture(u[0],u[1])

Original: https://www.cnblogs.com/LyShark/p/16652464.html
Author: lyshark
Title: Python 博客园备份迁移脚本

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/803470/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Flutter写的博客园客户端

    几个月前在博客园发帖说要用 Flutter写个客户端,版本也在陆陆续续的迭代当中,软件也日臻完善起来,想着就把它开源以作Flutter学习。 目前软件已经上线 Goolge Pla…

    Python 2023年10月11日
    048
  • 解决scrapy的无输出问题

    scrapy问题解决 ** scrapy无输出问题解决 ** 昨天跟着老师敲的时候,发现自己的scrapy无输出,心想:老师运行是对的,为什么我运行就是错的,于是在网络上疯狂寻找答…

    Python 2023年10月1日
    059
  • Matplotlib

    Matplotlib 1.axis轴:表示x,y轴 注:只有点(散点图) 只有线(折线图) from matplotlib import pyplot as plt x = ran…

    Python 2023年9月2日
    044
  • 使用 x-sheet 构建在线疫情高峰预测数据表

    背景 最近,一位大数据专家通过百度”发烧”的搜索指数、公开的疫情感染人数等指标,计算出每个城市的”超额发烧搜索指数累计面积”,并且通…

    Python 2023年9月28日
    051
  • 实训项目一:图书信息管理

    文章目录 一、提出任务 二、实现步骤 * (一)创建Django项目 – books (二)创建并注册应用 – index – 1、创建inde…

    Python 2023年8月5日
    093
  • Django 操作中的小技巧

    MODELS篇 1. 读取数据库中信息,生成下拉框 在views文件中生成创建下拉框的类,需要传入choice字段信息,格式类似[(),()],也可以是随意一个可迭代对象。假如要用…

    Python 2023年8月4日
    049
  • Python字典查找性能

    timeit.repeat默认会执行3轮,每轮执行1000000次。返回每轮的总执行时间列表 大家都知道字典获取分为 中括号获取,获取不到会抛出KeyError get获取,获取不…

    Python 2023年5月24日
    050
  • Flask框架:运用Ajax轮询动态绘图

    Ajax是异步JavaScript和XML可用于前后端交互,在之前 《Flask 框架:&a…

    Python 2023年10月30日
    035
  • 【Python 数据处理】Pandas

    Pandas 是 Python 语言的一个扩展程序库,用于数据分析。 Pandas 名字衍生自术语 “panel data”(面板数据)和 “P…

    Python 2023年8月6日
    049
  • LInux下部署基于Conda的Python虚拟环境

    前言 Anaconda 个人版包含conda 和Anaconda Navigator,以及 Python 和数百个科学 软件包。当你安装 Anaconda 时,你也安装了所有这些。…

    Python 2023年9月8日
    045
  • Python中的strip().split(‘t‘)的用法和解释

    目录 (一)、strip()的用法 (二)、split的用法 (三)、strip().split()的用法 (一)、strip()的用法 strip()主要是对字符串进行操作,主要…

    Python 2023年8月1日
    065
  • 机器学习入门——Numpy的基本用法

    从两个方向进行等量分割 print(np.split(A.T,2,axis=0)) print(np.split(A,2,axis=1)) 可以理解为axis指定了对矩阵的某一个维…

    Python 2023年8月25日
    054
  • python+selenium+pytesseract识别图片验证码

    Original: https://www.cnblogs.com/sn520/p/15777998.htmlAuthor: Python可乐呀Title: python+sele…

    Python 2023年5月24日
    074
  • 换工作?试试远程工作「GitHub 热点速览 v.22.40」

    近日,潜在某个技术交流群的我发现即将毕业的小伙伴在焦虑实习、校招,刚好本周 GitHub 热榜有个远程工作项目。不妨大家换个思路,”走”出去也许有更多的机会…

    Python 2023年10月19日
    063
  • 13. Django 博客项目02 站点主页&个人主页

    7. 主页 7.1 路由层 url(r’^home/’, views.home), 7.2 视图层 def home(request): return render(request…

    Python 2023年8月4日
    067
  • matplotlib如何设置散点图中点的像素大小

    工作中遇到的问题:matplotlib如何设置点的像素大小,具体情况如下图。解决方法:将plot方法更换为scatter方法,然后就可以指定s(像素属性)的值了。 方法说明: pl…

    Python 2023年9月2日
    051
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球