Python实现爬取WordPress文章并转换成CSDN/博客园文章格式

博客:https://mwhls.top/2186.html
GitHub:https://github.com/asd123pwj/wordpress_spider

推荐参考:Python爬虫入门

2022/4/5更新:适配了博客园格式,在首页爬取模式的基础上加入了文章归类批量爬取模式文章链接爬取模式

项目介绍

  • convert_wordpress_to_csdn.py
    • 爬取我的WordPress博客,并转换为CSDN格式、博客园可用格式。
    • CSDN直接粘贴。
      博客园使用TextBox编辑器。
    • 批量爬取首页的文章。
    • 批量爬取某个分类/标签/归档下的文章。
    • 根据文章链接爬取文章。
    • 为文章开头添加转载信息。
  • py2exe.py
    • convert_wordpress_to_csdn.py 放在同一目录下,运行后可生成exe文件。

项目思路

  1. 获取页面html文本

  2. 从博客主页获取文章链接

    • 分割的时候,re总是匹配最多的内容,而这些内容之间又有变动的东西,不能像上篇文章一样用split分片。
    • 即,使用 href=(.*) 匹配时,它总是从第一个href=匹配到最后一篇文章的“。
    • 然后查了几个方法,试了用re的split,但依然是同样问题,虽然分割了,但还是把不该包括的东西也包括进去了。
    • 最后在re的官方文档里面找到了解决办法:
    • 加一个?,将 (.*) 改成 (.*?),即可达到非贪婪匹配的效果,匹配最少的字符,
    • 见:https://docs.python.org/zh-cn/3/library/re.html
  3. 爬取上一步获取的链接对应的文章

    • 在转换成CSDN格式的时候,原本是打算用管理员账号的编辑模式页面,

    • 因为我一直都是用这个页面来发文章的。

    • 然后试了试直接爬取,可行,于是直接爬取。

    • 但在代码格式的处理中有问题,如果连续空两行,就会出问题。

    • 最后在代码标签前后加上了WordPress的code标签才解决。

  4. 输出结果

convert_wordpress_to_csdn.py

import re
import urllib.request
import urllib.error
from bs4 import BeautifulSoup
import pyperclip

def main():
    mode = input("""
选择爬取模式:
1. 从归类页面中批量爬取文章,回车直接进入。
2. 从文章链接中爬取文章内容,输入文章链接进入。
    """)
    if mode == '':
        get_from_page()
    else:
        get_from_post(mode)
    print("转换成功,程序正常结束。")

def get_from_post(post_url):
    html = ask_url_get_html(post_url)
    html_data = get_data_from_post_page(html, post_url)
    print('获取成功,文章标题已粘贴至剪切板。')
    pyperclip.copy(html_data[0])
    input("按下回车复制文章内容。")
    pyperclip.copy(html_data[1])
    input("已获取文章内容,按下回车继续。")

def get_from_page():
    page_url = input("请输入页面地址(回车爬取首页):")
    if page_url == '':
        page_url = "https://mwhls.top/"

    article_num = input("转换文章数(默认1,最多10):")
    if article_num == '':
        article_num = 1
    else:
        article_num = int(article_num)

    html = ask_url_get_html(page_url)
    url = get_url_from_homepage(html, article_num)

    for pos in range(article_num - 1, -1, -1):
        print('第{0}篇文章的html文本获取中...'.format(article_num - pos))
        html = ask_url_get_html(url[pos])
        html_data = get_data_from_post_page(html, url[pos])
        print('获取成功,文章标题已粘贴至剪切板。')
        pyperclip.copy(html_data[0])
        input("按下回车复制文章内容。")
        pyperclip.copy(html_data[1])
        input("已获取文章内容,按下回车继续。")

def ask_url_get_html(url):
    #   从url中获取html文件
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
    }
    request = urllib.request.Request(url, headers=head)
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html

def get_url_from_homepage(html, article_num):
    #   从主页中获得文章链接
    find_url = re.compile('href="(.*?)" rel=')
    soup = BeautifulSoup(html, "html.parser")
    item = str(soup.find_all("h2", class_='post-title', limit=article_num))
    url = re.findall(find_url, item)
    return url

def get_data_from_post_page(html, url):
    #   从文章页面获取信息并转换成CSDN格式
    find_content = re.compile('</div>(.*)]', re.DOTALL)
    find_title = re.compile('title">(.*)</h1>')
    soup = BeautifulSoup(html, "html.parser")
    item = str(soup.find_all("h1", class_='post-title'))
    title = re.findall(find_title, item)
    item = str(soup.find_all("div", class_='entry'))
    item = item.replace('<pre class="wp-block-code"><code>', '\n\n<!-- wp:code -->\n<pre class="wp-block-code"><code>')
    item = item.replace('</code></pre>', '</code></pre>\n<!-- wp:code -->\n')

    content = re.findall(find_content, item)
    content[0] = """
<p><em>文章首发及后续更新:<a href="{0}">{1}</a>,无图/无目录/格式错误/更多相关请至首发页查看。<br/> 
新的更新内容请到<a href="https://mwhls.top/">mwhls.top</a>查看。<br/> 
欢迎提出任何疑问及批评,非常感谢!</em></p>
    """.format(url, url) + content[0]
    html_data = []
    html_data.append(title[0])
    html_data.append(content[0])

    return html_data

if __name__ == '__main__':
    main()

py2exe.py

import os
os.system("pyinstaller -F  convert_wordpress_to_csdn.py")

You may also like...

发表评论

您的电子邮箱地址不会被公开。

CAPTCHAis initialing...