「保姆级」网络爬虫教程(二):教你下载文库中的PDF文档!

如何点赞再看,养成习惯。微信公众号搜索「Job Yan」关注这个爱发技术干货的 Coder。本文 GitHub https://github.com/JobYan/PythonPearls 已收录,还有算法学习、爬虫进阶等资料,以及我的系列文章,欢迎 Star 和完善。

大家好,我是 「Job」。本篇文章是「保姆级带你入门和进阶网络爬虫系列文章的第二篇,在本篇文章中我会手把手教你:如何下载文库中的 PDF 文档和 PPT 文档。温馨提示,本文字数较多,可能需要阅读较长时间,建议先点赞收藏,防止迷路。


大家好呀,我的文字终于又和大家见面了!上一次和大家见面大概是在 2020 年的 11 月,转眼间两年时间已经过去。这两年里社会上发生了很多重大的事件,我们也经历了很多,尤其是疫情期间,每天都上演着新冠病毒和人类之间发生的“没有硝烟的战争”,在这场战役中涌现出了众多志愿者,他们用自己的弱小的身躯筑起了抗击疫情的厚重城墙。在这段时间里我顺利完成了学业,并且步入了社会,由学生转变为职场人,慢慢地体会到了工作的压力和生活的不易。现在再回头看看之前立下的“长时间更新公众号文章”的小目标好像实现得并不太理想,两年的时间只产出了一篇文章,不知道你还有没有印象当时随手关注的公众号,竟然在自己的关注列表里躺平了2年多的时间。

上次写文档下载程序主要是为了学习爬虫相关的知识,顺便帮助有需要的小伙伴下载一些文档,本着「独乐乐不如众乐乐」的信条,我也将自己写的蹩脚的代码开源了,想着可以帮助一些朋友快速实现文库文档的获取。程序发布一段时间之后,得到了好多小伙伴的使用和认可,好景不长的是文库总是会有一些更新,包括页面的排版、链接的格式等,这些改动往往会导致之前通过正则匹配、选取样式等方式抓取 URL 的方法失效,由于上一版软件长时间未得到维护,最终,它毫无意外地失效了。

后边,我有关注文库的一些反爬策略,但迟迟没有动手编写新版的代码。最近,我想着在工作之余培养自己在爬虫方面的兴趣,顺便帮助有需要的小伙伴,所以又开始对软件进行维护了。

1. 软件是如何使用的?

上一版的软件采用控制台样式,直接在控制台中输入文档的链接,就可以下载文档中包含的图像,图像下载完成后,会将这些图像拼成一个PDF文件,所以最终会得到一组图片和一个PDF文件。程序的使用过程展示如下:

这个没有UI界面的程序使用起来不太友好,在易用上可能会劝退一部分小伙伴。因此,本次对程序进行了升级,首次加上了UI界面,虽然界面比较简陋,但是聊胜于无。在经过一段时间的开发之后,我打算将最近一段时间成果物展示给各位小伙伴,如果大家有文档下载方面需求的话,可以下载软件之后自己尝试一下。

需要说明的是本次开发的软件仅支持 PPT 文件和 PDF 文件的下载,暂不支持 WORD 文件和 TXT 文件的下载。

升级之后,程序的使用过程如下图所示,只需要将文档的链接粘贴到文本框中,点击下载即可得到一组图片和 PDF 文件。当然,这次还贴心的实现了「更改下载文件夹」和「打开下载文件夹」的功能,可以方便的修改保存路径和打开下载路径。

img

按照以往的惯例,本次的代码依旧会开源,我已经将代码托管在 GitHub 上了,如果有对这方面有兴趣的小伙伴,可以下载源码并进行改进。很希望这个小软件能为你的工作或学习带来一点点的帮助。

2. 软件是如何实现的?

软件实现的思路很简单,这次直接把上次文章中画的流程图拿了过来。

从上图可以看出,总共分为 4 步:

  1. 获取文档的网页链接
    首先要获取文档的链接,这个链接也就是需要小伙伴们动手获取,并粘贴到文本框中的链接。

  2. 解析网页内容,获取图片资源的链接
    获取文档链接对应的 HTML 文件并利用「正则表达式」或者「Beautiful Soup」对 HTML 内容进行解析,获取到图片资源的链接。

  3. 从上述链接下载对应的图片文件
    对上一步获取到的链接依次进行爬取,并将文件以图片的格式保存到本地。

  4. 合并内容并保存到本地 PDF 文件
    利用 fitz 库将图片文件合并为 PDF 文件。

从上述的流程中可以发现,重点在于第 2 步,即如何从 HTML 文件中获取图片链接是本文要讲解的重点。

上一篇文章中讲解了如何爬取 PPT 文档,有兴趣的小伙伴可以去翻开上一篇文档看一下,本次主要介绍如何爬去 PDF 文档。

2.1 获取 HTML 文件

# 带下载的文档链接
url = "https://wenku.baidu.com/view/e966626f7cd184254b3535d7"
# 构造 header
user_agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
header = {'User-Agent': user_agent}
# 首先访问文库官网,获取cookies,骗过防爬机制
res = requests.get('https://wenku.baidu.com', headers=header)  
cookie = res.cookies
# 获取文档链接的网页内容
html_content = requests.get(url, headers=self.header, cookies=cookie).content

2.2 利用正则表达式解析网页内容,获取图片链接

获取到的网页内容如下,为了便于展示,对原网页的内容进行了部分删减。从下面的内容中可以看出,json 和 png 都是按照「页」的格式来填充的。pageIndex 表示页码,后面的 pageLoadUrl 字段为 json 或 png 的链接,如果能获取该链接,就可以获取到 PDF 的文本和图片。

<meta charset="utf-8">\n    <title>\xe4\xb8\xad\xe5\x8d\x8e\xe6\xb0\x91\xe5\x9b\xbd\xe5\x9c\xb0\xe5\x9b\xbe\xe9\x9b\x86 - \xe7\x99\xbe\xe5\xba\xa6\xe6\x96\x87\xe5\xba\x93</title>\n
<!-- 此处为json文件信息,json文件中包含PDF中的文字 -->
"json":[{"pageIndex":1,"pageLoadUrl":"https://wkbjcloudbos.bdimg.com/v1/docconvert3273/wk/cbf845cb74352d6a2c27bef96588c94b/0.json?responseContentType=application%2Fjavascript&responseCacheControl=max-age%3D3888000&responseExpires=Wed%2C%2001%20Feb%202023%2016%3A48%3A35%20%2B0800"},{"pageIndex":2,"pageLoadUrl":"https://wkbjcloudbos.bdimg.com/v1/docconvert3273/wk/cbf845cb74352d6a2c27bef96588c94b/0.json?responseContentType=application%2Fjavascript&responseCacheControl=max-age%3D3888000&responseExpires=Wed%2C%2001%20Feb%202023%2016%3A48%3A35%20%2B0800"}]
<!-- 此处为json文件信息,json文件中包含PDF中的图片 -->
"png":[{"pageIndex":1,"pageLoadUrl":"https://wkbjcloudbos.bdimg.com/v1/docconvert3273/wk/cbf845cb74352d6a2c27bef96588c94b/0.png?responseContentType=image%2Fpng&responseCacheControl=max-age%3D3888000&responseExpires=Wed%2C%2001%20Feb%202023%2016%3A48%3A35%20%2B0800"},{"pageIndex":2,"pageLoadUrl":"https://wkbjcloudbos.bdimg.com/v1/docconvert3273/wk/cbf845cb74352d6a2c27bef96588c94b/0.png?responseContentType=image%2Fpng&responseCacheControl=max-age%3D3888000&responseExpires=Wed%2C%2001%20Feb%202023%2016%3A48%3A35%20%2B0800"}]},"freePage":23,"showPage":2,"page":23,"originalPage":23

由于网页上文本的排版较为复杂,如果仅获取文字,也无法较好地还原网页上显示的页面,因此,本软件只是实现了图片文件的获取。针对上述网页内容,通过正则表达式可以快速提取出 png 文件所对应的链接。

links = re.findall("\"png\"\:\[(.*?)\]", html_content.decode('utf-8'))  
if links:  
    self.link_list = re.findall("\"pageIndex\"\:\d+\,\"pageLoadUrl\"\:\"(.*?)\"\}", links[0])

2.3 依次下载图片

利用下面的下载函数,依次把正则表达式提取到的 png 图像链接下载下来。

def download(url, user_agent="wswp", num_retries=2):  
    # print("Downloading: ", url)  
    headers = {"User-agent": user_agent}  
    request = urllib.request.Request(url, headers=headers)  
    try:  
        html = urllib.request.urlopen(request)  
        # print(html.read().decode("utf-8"))  
    except urllib.error.URLError as e:  
        # print("Download error: ", e.reason)  
        html = None  
        if num_retries > 0:  
            if hasattr(e, 'code') and 500 <= e.code <= 600:  
                # 如果是5xx错误,则进行重试  
                return download(url, user_agent, num_retries - 1)  
    return html

2.4 将图片合并为PDF文件

借助 fitz 库的帮助,将下载好的 png 图像合并成一个 PDF 文件。

def export_pdf(self, dir, pdf_name, img_paths):  
    doc = fitz.open()  
    for img_path in img_paths:  
        imgdoc = fitz.open(img_path)  # 打开图片  
        pdfbytes = imgdoc.convert_to_pdf()  # 使用图片创建单页的 PDF  
        imgpdf = fitz.open("pdf", pdfbytes)  
        doc.insert_pdf(imgpdf)  # 将当前页插入文档  
  
    # 保存在图片文件夹下  
    save_pdf_path = os.path.join(dir, pdf_name)  
    if os.path.exists(save_pdf_path):  
        os.remove(save_pdf_path)  
  
    doc.save(save_pdf_path)  # 保存pdf文件  
    doc.close()

3. 软件的一些说明

  1. 本软件会永久开源并且永不收费,仅供喜欢爬虫技术的小伙伴们学习使用;
  2. 软件可能会由于各种原因而不能使用,请不要依赖此软件;
  3. 本次开发的软件仅支持 PPT 文件和 PDF 文件的下载,暂不支持 WORD 文件和 TXT 文件的下载;
  4. 软件爬取到的文件和文库中的原文件是有区别的,以PPT类型的文件为例,我们在文档页面看到的内容其实是 PPT 经过渲染后的图片。所以我们可以利用 Python 等编写爬虫脚本,爬取网页中的相关图片,再将这些图片合并成 PDF 文档。如果想要获取可编辑的 PPT 文件,可能需要你用「钞能力」支持一下文库。

4. 如何获取软件


如果我的文章帮到了你,请给一个小心心🥰,有了你的鼓励我后续会更有动力创作出更加优质的文章,从而帮助到更多的小伙伴。当然,如果你觉得本文章在某些方面是不够好的,请在评论区留言,你的意见对我真的非常重要,谢谢。

我已经将本文章中讲述的源码都打包好了,并且还利用 pyinstaller 生成了可执行文件,如果你有这方面需求的话,请关注公众号「Job Yan」,后台回复百度文库,即可获取相关文件,后期程序更新的话,我会第一时间将相应文件更新到微信公众号后台。本系列教程持续更新,如果你也对爬虫感兴趣,欢迎关注,咱们共同进步,一起成长。

欢迎各位小伙伴用你们心爱的大手机扫描屏幕上的二维码(长按二维码可以识别或者保存到本地哟😘)。这是个套了支付宝马甲的公众号二维码,不信你就扫扫看(手动斜眼)。

文章持续更新,可以微信公众号搜索「Job Yab」第一时间阅读,本文 GitHub https://github.com/JobYan/PythonPearls 已经收录,还有算法学习、爬虫进阶等资料,欢迎 Star 和完善。

posted @ 2022-12-18 23:12  JobYan  阅读(1701)  评论(0编辑  收藏  举报