python基于pyppeteer制作PDF文件
Pyppeteer 是什么
介紹 Pyppeteer 之前,有必要先介紹一下 Puppeteer,Puppeteer 是谷歌官方出的一個(gè)通過DevTools協(xié)議控制headless Chrome的Node庫(kù)。通過Puppeteer可以直接控制Chrome瀏覽器模擬大部分用戶操作。
所謂Headless Chrome 就是 Chrome 瀏覽器的無界面形態(tài)。
而 Pyppeteer 就是 Puppeteer 的 Python 版本非官方實(shí)現(xiàn),它是一位來自于日本的工程師依據(jù) Puppeteer 的一些功能開發(fā)出來的非官方版本
Pyppeteer 采用了 Python 的 async 機(jī)制,需要Python3.5 及以上版本才支持。
Pyppeteer能做什么
但凡是需要通過Chrome瀏覽器手動(dòng)完成的操作都可以通過 Pyppeteer 自動(dòng)完成,例如:
- 生成頁面截圖
- 生成PDF文件
- 抓取單頁面應(yīng)用并生成預(yù)先呈現(xiàn)的內(nèi)容
- 從網(wǎng)站抓取你需要的內(nèi)容
- 自動(dòng)表單提交,UI測(cè)試,鍵盤輸入等
截圖
例如將頁面生成截圖可以直接調(diào)用 page.screenshot 方法
import asyncio
from pyppeteer import launch
async 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())
截圖功能在海報(bào)分享等場(chǎng)景用的多,有看過有贊工程師分享的一篇文章,就有用到Puppeteer來做海報(bào)分享,性能比Canvas高。
而將網(wǎng)頁轉(zhuǎn)換為PDF的應(yīng)用場(chǎng)景更多,比如將網(wǎng)站博客、專欄,或者公眾號(hào)文章批量導(dǎo)出PDF,方便離線閱讀,比如我們最近做的一個(gè)醫(yī)療項(xiàng)目需要將用戶填寫的資料支持PDF形式批量導(dǎo)出,就是用的Pyppeteer
導(dǎo)出PDF
導(dǎo)出pdf直接調(diào)用page.pdf方法就可以, 代碼非常簡(jiǎn)潔
import asyncio
from pyppeteer import launch
async 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())
接下來我們以公眾號(hào)文章為例,將html頁面制作成一個(gè)PDF文件。
公眾號(hào)鏈接導(dǎo)出PDF示例
安裝 pyppeteer
pip install pyppeteer
任意找一篇公眾號(hào)的文章鏈接
url = "https://mp.weixin.qq.com/s/6VBXs19icV0O5hT7cHYwgw"
完成代碼:
browser = await launch(
options={'headless': True,
'args': ['--no-sandbox',
'–disable-gpu',
'–disable-dev-shm-usage',
'–disable-setuid-sandbox',
'–no-first-run',
'–no-zygote',
'–single-process'
]}, )
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()
第一次運(yùn)行的時(shí)候,會(huì)自動(dòng)下載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
執(zhí)行完成后,我們來預(yù)覽下pdf文件

和原文鏈接對(duì)比,發(fā)現(xiàn)文章中的圖片丟失了。
通過分析,原來是頁面源代碼中,img 標(biāo)簽沒有src屬性,只有個(gè)data-src 屬性,默認(rèn)情況下圖片是無法正常顯示的,圖片之所有能在瀏覽器能正常展示出來,是有個(gè)js腳本動(dòng)態(tài)地修改了dom元素為 <img src='xxxx'>

這個(gè)網(wǎng)頁使用的是一種叫懶加載的技術(shù)展示圖片內(nèi)容,所謂懶加載就是圖片不會(huì)一次全部下載完,而是當(dāng)前瀏覽到什么位置,就加載該處的圖片,這樣能提高頁面的響應(yīng)速度,同時(shí)減輕服務(wù)器性能。
所以,我們也可以通過js代碼模擬真人瀏覽網(wǎng)頁一樣,滾動(dòng)鼠標(biāo),不停地往下滑動(dòng),將圖片動(dòng)態(tài)加載出來。
最后,完整代碼就變成了這樣:
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 new
Promise((resolve, reject) => {
var
totalHeight = 0;
var
distance = 100;
var
timer = setInterval(() => {
var
scrollHeight = 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 代碼封裝成一個(gè)字符串當(dāng)作參數(shù)傳給 page.evaluate 函數(shù), 該代碼就是獲不斷滾動(dòng)頁面,直到頁面底部為止。這樣整個(gè)頁面的圖片就全部加載出來了。
效果看起來還不錯(cuò),和原頁面的樣式是一樣的

在Pyppeteer實(shí)踐應(yīng)用過程中,也遇到不少坑,最后都逐個(gè)解決了,這可以單獨(dú)寫一篇文章,如果你在使用過程中遇到任何問題歡迎與我交流
以上就是python基于pyppeteer制作PDF文件的詳細(xì)內(nèi)容,更多關(guān)于python pyppeteer制作PDF文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python第三方庫(kù)h5py_讀取mat文件并顯示值的方法
今天小編就為大家分享一篇Python第三方庫(kù)h5py_讀取mat文件并顯示值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02
Python編程itertools模塊處理可迭代集合相關(guān)函數(shù)
本篇博客將為你介紹Python函數(shù)式編程itertools模塊中處理可迭代集合的相關(guān)函數(shù),有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09
python網(wǎng)絡(luò)爬蟲精解之正則表達(dá)式的使用說明
正則表達(dá)式是對(duì)字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個(gè)“規(guī)則字符串”,這個(gè)“規(guī)則字符串”用來表達(dá)對(duì)字符串的一種過濾邏輯2021-09-09
python訪問mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法(2則示例)
這篇文章主要介紹了python訪問mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了兩種Python操作MySQL數(shù)據(jù)庫(kù)的相關(guān)技巧,需要的朋友可以參考下2016-01-01
python-web根據(jù)元素屬性進(jìn)行定位的方法
這篇文章主要介紹了python-web根據(jù)元素屬性進(jìn)行定位的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Spyder中如何設(shè)置默認(rèn)python解釋器
Spyder作為一款流行的Python IDE,支持用戶自定義Python解釋器,包括虛擬環(huán)境的設(shè)置,通過打開Spyder,選擇“Tools”->“Preferences”,在彈出窗口中選擇“Use the following Python interpreter”后,瀏覽并選擇相應(yīng)的解釋器或虛擬環(huán)境路徑2024-09-09
用Python編寫一個(gè)簡(jiǎn)單的Lisp解釋器的教程
這篇文章主要介紹了用Python編寫一個(gè)簡(jiǎn)單的Lisp解釋器的教程,Lisp是一種源碼簡(jiǎn)單的函數(shù)式編程語言,本文主要介紹對(duì)其中的一個(gè)子集Scheme的解釋器開發(fā),需要的朋友可以參考下2015-04-04
python實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(精簡(jiǎn)版)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)的精簡(jiǎn)版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
Python3實(shí)現(xiàn)的Mysql數(shù)據(jù)庫(kù)操作封裝類
這篇文章主要介紹了Python3實(shí)現(xiàn)的Mysql數(shù)據(jù)庫(kù)操作封裝類,涉及Python針對(duì)mysql數(shù)據(jù)庫(kù)的連接、查詢、更新及關(guān)閉連接等相關(guān)操作技巧,需要的朋友可以參考下2018-06-06

