神器:用 pyppeteer 转换公众号文章为 PDF

2024-05-15 12:18

本文主要是介绍神器:用 pyppeteer 转换公众号文章为 PDF,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是「进击的Coder」的第 368 篇技术分享

作者:刘志军

来源:Python 之禅

阅读本文大概需要 8 分钟。

之前介绍过一些将 html 转换为 PDF 文件的库,比如 wkhtmltopdf、WeasyPrint,今天再介绍另一个神器 Pyppeteer 可将 html 页面转换为 PDF。

Pyppeteer 是什么

介绍 Pyppeteer 之前,有必要先介绍一下 Puppeteer,Puppeteer 是谷歌官方出的一个通过 DevTools 协议控制 headless Chrome 的 Node 库。通过 Puppeteer 可以直接控制 Chrome 浏览器模拟大部分用户操作。

所谓 Headless Chrome 就是 Chrome 浏览器的无界面形态。

而 Pyppeteer 就是 Puppeteer 的 Python 版本非官方实现,它是一位来自于日本的工程师依据 Puppeteer 的一些功能开发出来的非官方版本。

Pyppeteer 采用了 Python 的 async 机制,需要 Python3.5 及以上版本才支持。

Pyppeteer 能做什么

但凡是需要通过 Chrome 浏览器手动完成的操作都可以通过 Pyppeteer 自动完成,例如:

  • 生成页面截图

  • 生成 PDF 文件

  • 抓取单页面应用并生成预先呈现的内容

  • 从网站抓取你需要的内容

  • 自动表单提交,UI 测试,键盘输入等

截图

例如将页面生成截图可以直接调用 page.screenshot 方法

import asyncio
from pyppeteer import launchasync def main():browser = await launch()page = await browser.newPage()await page.goto('https://foofish.net')await page.screenshot({'path': 'example.png'})await browser.close()asyncio.get_event_loop().run_until_complete(main())

截图功能在海报分享等场景用的多,有看过有赞工程师分享的一篇文章,就有用到 Puppeteer 来做海报分享,性能比 Canvas 高。


而将网页转换为 PDF 的应用场景更多,比如将网站博客、专栏,或者公众号文章批量导出 PDF,方便离线阅读,比如我们最近做的一个医疗项目需要将用户填写的资料支持 PDF 形式批量导出,就是用的 Pyppeteer

导出 PDF

导出 pdf 直接调用 page.pdf  方法就可以, 代码非常简洁

import asyncio
from pyppeteer import launchasync def main():browser = await launch()page = await browser.newPage()await page.goto('https://foofish.net')await page.pdf({"path": "example.pdf", "format": 'A4'})await browser.close()asyncio.get_event_loop().run_until_complete(main())

接下来我们以公众号文章为例,将 html 页面制作成一个 PDF 文件。

公众号链接导出 PDF 示例

安装 pyppeteer

pip install pyppeteer

任意找一篇公众号的文章链接

 url = "https://mp.weixin.qq.com/s/6VBXs19icV0O5hT7cHYwgw"

完成代码:

    browser = await launch()page = await browser.newPage()url = "https://mp.weixin.qq.com/s/6VBXs19icV0O5hT7cHYwgw"await page.goto(url)file_name = "test.pdf"await page.pdf({"path": file_name, "format": 'A4'})await browser.close()

第一次运行的时候,会自动下载 chromium 浏览器,chromium 是 chrome 的开源版本, 需要几分钟才能下载完

[W:pyppeteer.chromium_downloader] start chromium download.
Download may take a few minutes.
100%|██████████| 127496521/127496521 [00:20<00:00, 6268578.80it/s]
[W:pyppeteer.chromium_downloader] 
chromium download done.
[W:pyppeteer.chromium_downloader] chromium extracted to: C:\Users\lzjun\AppData\Local\pyppeteer\pyppeteer\local-chromium\575458

执行完成后,我们来预览下 pdf  文件

和原文链接对比,发现文章中的图片丢失了。

通过分析,原来是页面源代码中,img 标签没有 src 属性,只有个 src 属性,默认情况下图片是无法正常显示的,图片之所有能在浏览器能正常展示出来,是有个 js 脚本动态地修改了 dom 元素为 <img src='xxxx'>

这个网页使用的是一种叫懒加载的技术展示图片内容,所谓懒加载就是图片不会一次全部下载完,而是当前浏览到什么位置,就加载该处的图片,这样能提高页面的响应速度,同时减轻服务器性能。

所以,我们也可以通过js代码模拟真人浏览网页一样,滚动鼠标,不停地往下滑动,将图片动态加载出来。

最后,完整代码就变成了这样:

async def main():browser = await launch()page = await browser.newPage()url = "https://mp.weixin.qq.com/s/6VBXs19icV0O5hT7cHYwgw"await page.goto(url)await page.evaluate('''async () => {await newPromise((resolve, reject) => {vartotalHeight = 0;vardistance = 100;vartimer = setInterval(() => {varscrollHeight = document.body.scrollHeight;window.scrollBy(0, distance);totalHeight += distance;if (totalHeight >= scrollHeight){clearInterval(timer);resolve();}}, 100);});}''')await page.pdf({"path": "test.pdf", "format": 'A4'})await browser.close()if __name__ == '__main__':asyncio.get_event_loop().run_until_complete(main())

将 js 代码封装成一个字符串当作参数传给 page.evaluate 函数, 该代码就是不断滚动页面,直到页面底部为止。这样整个页面的图片就全部加载出来了。

效果看起来还不错,和原页面的样式是一样的(点击图片放大查看)

在 Pyppeteer 实践应用过程中,也遇到不少坑,最后都逐个解决了,这可以单独写一篇文章,如果你在使用过程中遇到任何问题欢迎与我交流。

End

「进击的Coder」专属学习群已正式成立,搜索「CQCcqc4」添加崔庆才的个人微信或者扫描下方二维码拉您入群交流学习。

看完记得关注@进击的Coder

及时收看更多好文

↓↓↓

赶紧动手试一试

这篇关于神器:用 pyppeteer 转换公众号文章为 PDF的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991817

相关文章

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩

SpringBoot集成EasyPoi实现Excel模板导出成PDF文件

《SpringBoot集成EasyPoi实现Excel模板导出成PDF文件》在日常工作中,我们经常需要将数据导出成Excel表格或PDF文件,本文将介绍如何在SpringBoot项目中集成EasyPo... 目录前言摘要简介源代码解析应用场景案例优缺点分析类代码方法介绍测试用例小结前言在日常工作中,我们经

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方