一、概要
这段代码主要用于从人民日报网站下载特定日期的PDF版本,并将这些PDF文件合并为一个完整的PDF文件。注意,在运行代码之前,需要确保已经安装了requests库(用于网络请求)和python-office库(用于PDF合并)。
pip install python-office
二、整体架构流程
这段代码主要用于从人民日报网站下载特定日期的PDF版本,并将这些PDF文件合并为一个完整的PDF文件。注意,在运行代码之前,需要确保已经安装了requests库(用于网络请求)和python-office库(用于PDF合并)。下面是关于代码的详细技术细节:
-
模块导入:代码使用了Python的内置模块
os
和re
,以及第三方库requests
和office
。其中,os
模块用于处理操作系统相关的功能,如文件和目录操作;re
模块用于正则表达式操作;requests
库用于发出HTTP请求;office
库用于合并PDF文件。 -
函数定义:代码定义了6个函数,分别是
create_folder
、delete_pdf
、convert_date_format
、extract_page_links
、download_pdfs
、merge_pdfs
和get_detail
。create_folder(path)
: 使用os.makedirs()
函数创建一个目录,如果目录已经存在,则不会抛出异常。delete_pdf(pdf_path)
: 删除指定路径下所有非“完整版”的PDF文件。convert_date_format(date)
: 将日期从一种格式转换为另一种格式,例如从"20230705"转换为"2023-07/05"。extract_page_links(page_text)
: 从给定的HTML文本中提取所有PDF文件的链接和标题。download_pdfs(date, date_format, page_link, path)
: 根据提取的链接下载所有PDF页面,并将它们保存在指定的路径下。merge_pdfs(download_list, path, date)
: 将下载的PDF列表合并为一个完整的PDF文件,并将它保存在指定的路径下。get_detail(date)
: 这是主函数,它调用上述所有函数。首先,它转换日期格式,然后获取指定日期的HTML文本,从中提取PDF链接,下载这些PDF文件,将它们合并为一个完整的PDF文件,最后删除非完整版的PDF文件。
-
日期格式:代码中的日期格式转换假设输入的日期是一个字符串,格式为"YYYYMMDD"。
-
正则表达式:在
extract_page_links
函数中,使用了一个正则表达式来提取HTML中的链接和标题。该正则表达式的模式为<a id=pageLink href=(.*?)>(.*?)</a>
。 -
文件操作:在下载PDF文件时,代码使用二进制写入模式(‘wb’)打开文件,并使用响应内容(
r.content
)写入文件。 -
合并PDFs:使用
office.pdf.merge2pdf()
函数将所有下载的PDF文件合并为一个完整的PDF。 -
删除非完整版PDFs:在合并完所有PDF后,调用
delete_pdf()
函数删除所有非完整版的PDF文件。 -
异常处理:尽管代码没有明确包含异常处理块,但在下载和合并PDF时可能会抛出异常,例如网络连接问题或磁盘空间不足。
三、完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022-11-06 9:38
# @Author : Leuanghing Chen
# @Blog : https://blog.csdn.net/weixin_46153372?spm=1010.2135.3001.5421
# @File : 爬取人民日报并生成完整pdf文件.py
# @Software : PyCharm
import requests
import re
import os
import office # 导入这个库:python-office,简写为office
# 判断文件夹是否存在,若不存在,则创建
def create_folder(path):
os.makedirs(path, exist_ok=True)
# 删除合并前文件
def delete_pdf(pdf_path):
# pdf_path = D:\python_demo\爬取人民日报并生成完整pdf文件\rmrb20230516
pdf_path = pdf_path + "\\"
for file_name in os.listdir(pdf_path):
if "完整版" not in file_name:
os.remove(pdf_path + file_name)
# pdf的url处理
def convert_date_format(date):
years = date[0:4]
month = date[4:6]
day = date[6:8]
return years + '-' + month + '/' + day
# 提取当日每一页标题及url
def extract_page_links(page_text):
pat_link_href = r'<a id=pageLink href=(.*?)>(.*?)</a>'
return re.findall(pat_link_href, page_text, re.S)
# 下载每一页的pdf文件
def download_pdfs(date, date_format, page_link, path):
download_list = []
for i in range(len(page_link)):
num = "{:0>2.0f}".format(i + 1)
url = 'http://paper.people.com.cn/rmrb/images/{}/{}/rmrb{}{}.pdf'.format(date_format, num, date, num)
r = requests.get(url, stream=True)
print("Downloading page {}:".format(i + 1), url, page_link[i][1])
download_path = r'{}\rmrb{}{}.pdf'.format(path, date, "{:0>2.0f}".format(i + 1))
with open(download_path, 'wb') as f:
f.write(r.content)
download_list.append(download_path)
return download_list
# 合并pdf:参数作用:one_by_one = 是个列表,里面是2个pdf文件,合并后,a在前面,b在后面output =合并后的pdf名字,不能为空
def merge_pdfs(download_list, path, date):
office.pdf.merge2pdf(one_by_one=download_list, output=path + r'\rmrb{}(完整版).pdf'.format(date))
# 主函数
def get_detail(date):
try:
date_format_conversion = convert_date_format(date)
headers = {
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Mobile Safari/537.36'}
url = 'http://paper.people.com.cn/rmrb/html/{}/nbs.D110000renmrb_01.htm'.format(date_format_conversion)
page_text = requests.get(url=url, headers=headers).content.decode('utf-8')
page_link = extract_page_links(page_text)
path = r'D:\python_demo\爬取人民日报并生成完整pdf文件\rmrb{}'.format(date)
create_folder(path)
download_list = download_pdfs(date, date_format_conversion, page_link, path)
merge_pdfs(download_list, path, date)
delete_pdf(path)
except Exception as e:
print("Error: {}.The newspaper has not been updated!".format(e))
if __name__ == '__main__':
get_detail(input("输入日期(例:20221106):"))
print("Download complete!")