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

今天和大家聊聊如何把html网页制作成pdf

首先,我们先来看一下制作的思路:

html转pdf并打印 python html如何转pdf_从另一页面调用html代码

我们首先获取到网页的源代码,并保存在本地,然后利用pdfkit第三方库转换成pdf文档。

这里,我爬取了一位博主的所有文章,最终效果如下:

html转pdf并打印 python html如何转pdf_从另一页面调用html代码_02

操作步骤如下:

1、下载驱动

下载地址:https://wkhtmltopdf.org/downloads.html

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    html> 20     21         22             23         24         25            {content} 26         27     28    """
 29
 30class CSDN_2_PDF(object):
 31
 32    def __init__(self,blog_url):
 33        """ 34        初始化参数 35        """
 36        self.csdn_url = ''
 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[@]/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()

这里我直接定义了一个CSDN_2_PDF类来封装htmlpdf 的功能。后续,我们只需要实例化一个CSDN_2_PDF类对象,并传入个人博客地址即可。

代码的注释已经写得很清楚了,接下来,对代码做简单的介绍。

思路分析

我们从run方法开始看起,

在提取文章链接之前,首先需要动态获取cookie信息,才能够爬取到所有的文章。

我们需要提取到所有文章,但是我们并不知道作者写了多少篇文章,所以我们直接写一个大一点的数,直接写个1万。然后再做一层判断,如果返回到的文章链接为空,那么就退出循环。这样就可以确保提取到所有的文章链接。

但是我们并不需要整个网页的内容,所以只对网页的article标签做提取,然后再拼接成一个完整的html文档保存下来。为了下载下来的文档不那么乱,这里我们创建一个html文件夹,用来保存下载的html文件,创建一个pdf文件夹用来保存转换后的文件。

最后,调用具体实现转换功能的html_2_pdf方法,实现html 转 pdf的功能

需要注意的是,我们在保存html文章的时候,有时候标题会有特殊字符,这时候我们需要用正则表达式把特殊字符过滤掉。示例代码如下:

1title = re.sub('[\/:*?"<>|]', '-', title)  # 去掉标题中的非法字符

最后,我们需要做一个容错处理,在实现html 转 pdf功能的时候,有时候,如果html文档中存在图片资源访问不到的情况,就会出现转换失败。所以,我们需要做一层异常的处理。

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