vlambda博客
学习文章列表

如何把 html网页 转换为 pdf 文档呢?


目标:批量提取csdn文章,制成pdf文档

今天和大家聊聊如何把html网页制作成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文档中存在图片资源访问不到的情况,就会出现转换失败。所以,我们需要做一层异常的处理。

以上,就是对整个书写代码的注解啦。

如果对你有所帮助或启发,请不要吝惜你的在看哦。毕竟,有更多人在看的话,写东西动力也会强一点。

关注哥们并肩走过

与你分享我的

生活趣事/好物推荐/旅行见闻/编程思考