如何把 html网页 转换为 pdf 文档呢?
目标:批量提取csdn文章,制成pdf文档
今天和大家聊聊如何把html
网页制作成pdf
首先,我们先来看一下制作的思路:
我们首先获取到网页的源代码,并保存在本地,然后利用pdfkit第三方库转换成pdf文档。
这里,我爬取了一位博主的所有文章,最终效果如下:
操作步骤如下:
1、下载驱动
2、安装所需要的库
1pip install pdfkit
3、编写代码
示例代码如下:
1import requests
2import parsel
3import pdfkit
4import os
5import re
6from lxml import etree
7
8
9# 多个请求之间共享cookie
10session = requests.session()
11
12# 请求头
13headers = {
14 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
15 }
16
17# html模板
18html_template = """
19 <!DOCTYPE html>
20 <html lang="en">
21 <head>
22 <meta charset="UTF-8">
23 </head>
24 <body>
25 {content}
26 </body>
27 </html>
28 """
29
30class CSDN_2_PDF(object):
31
32 def __init__(self,blog_url):
33 """
34 初始化参数
35 """
36 self.csdn_url = 'https://www.csdn.net/'
37 self.blog_url = blog_url # 个人博客
38 self.driver = r'C:\wkhtmltopdf\bin\wkhtmltopdf.exe' # 驱动程序
39
40 def get_cookies(self):
41 """
42 获取cookies信息
43 :return:
44 """
45 session.get(self.csdn_url, headers=headers)
46
47 def get_article_link(self,url):
48 """
49 提取一页的文章链接
50 :return:
51 """
52 response = session.get(url, headers=headers)
53 html = etree.HTML(response.text)
54 # 提取一页文章所有链接
55 article_links = html.xpath('//div[@class="article-item-box csdn-tracking-statistics"]/h4/a/@href')
56 return article_links
57
58 def get_ariticle_html(self,link):
59 """
60 提取文章内容
61 :return:
62 """
63 response = session.get(link, headers=headers)
64 sel = parsel.Selector(response.text)
65 title = sel.css('.title-article::text').get()
66 title = re.sub('[\/:*?"<>|]', '-', title) # 去掉标题中的非法字符
67 article = sel.css('article').get()
68 return title, article
69
70 def html_2_pdf(self,filename_html,filename_pdf):
71 """
72 html 转 pdf
73 :param filename_html: html文件名
74 :param filename_pdf: pdf文件名
75 :return:
76 """
77 config = pdfkit.configuration(wkhtmltopdf=self.driver)
78 pdfkit.from_file(filename_html, filename_pdf,configuration=config)
79
80
81 def run(self):
82 # 1、获取cookie信息
83 self.get_cookies()
84 # 2、提取文章链接
85 all_article_links = []
86 for page in range(1,1000):
87 url = self.blog_url + '//article/list/%s'%(page)
88 article_links = self.get_article_link(url)
89 if article_links:
90 all_article_links.extend(article_links)
91 else:
92 break
93 # 3、提取文章内容
94 html_dir = r"html"
95 pdf_dir = r"pdf"
96 if not os.path.exists(html_dir):
97 os.makedirs(html_dir) # 创建一个html文件夹,用于存放所有html文件
98 if not os.path.exists(pdf_dir):
99 os.makedirs(pdf_dir) # 创建一个pdf文件夹,用于存放所有pdf文件
100 for link in all_article_links:
101 title,article = self.get_ariticle_html(link)
102 # 拼接成完整的html文档
103 html = html_template.format(content=article)
104 # 保存html
105 with open(f'{html_dir}/{title}.html', 'w', encoding='utf-8') as f:
106 f.write(html)
107 # 保存pdf
108 try:
109 self.html_2_pdf(f'{html_dir}/{title}.html', f'{pdf_dir}/{title}.pdf')
110 print("成功保存 => %s" % (title))
111 except:
112 print("转换失败 = > %s"% (title))
113
114
115if __name__ == '__main__':
116 blog_url = input("请输入爬取个人博客地址:")
117 p = CSDN_2_PDF(blog_url)
118 p.run()
代码的注释已经写得很清楚了,接下来,对代码做简单的介绍。
思路分析
我们从run
方法开始看起,
在提取文章链接之前,首先需要动态获取cookie信息,才能够爬取到所有的文章。
我们需要提取到所有文章,但是我们并不知道作者写了多少篇文章,所以我们直接写一个大一点的数,直接写个1万。然后再做一层判断,如果返回到的文章链接为空,那么就退出循环。这样就可以确保提取到所有的文章链接。
但是我们并不需要整个网页的内容,所以只对网页的article
标签做提取,然后再拼接成一个完整的html文档保存下来。为了下载下来的文档不那么乱,这里我们创建一个html文件夹,用来保存下载的html文件,创建一个pdf文件夹用来保存转换后的文件。
最后,调用具体实现转换功能的html_2_pdf
方法,实现html 转 pdf的功能
需要注意的是,我们在保存html文章的时候,有时候标题会有特殊字符,这时候我们需要用正则表达式把特殊字符过滤掉。示例代码如下:
1title = re.sub('[\/:*?"<>|]', '-', title) # 去掉标题中的非法字符
最后,我们需要做一个容错处理,在实现html 转 pdf
功能的时候,有时候,如果html文档中存在图片资源访问不到的情况,就会出现转换失败。所以,我们需要做一层异常的处理。
以上,就是对整个书写代码的注解啦。
如果对你有所帮助或启发,请不要吝惜你的在看哦。毕竟,有更多人在看的话,写东西动力也会强一点。
关注哥们并肩走过
与你分享我的
生活趣事/好物推荐/旅行见闻/编程思考