python基于pyppeteer制作PDF文件
介紹 Pyppeteer 之前,有必要先介紹一下 Puppeteer,Puppeteer 是谷歌官方出的一個(gè)通過(guò)DevTools協(xié)議控制headless Chrome的Node庫(kù)。通過(guò)Puppeteer可以直接控制Chrome瀏覽器模擬大部分用戶操作。
所謂Headless Chrome 就是 Chrome 瀏覽器的無(wú)界面形態(tài)。
而 Pyppeteer 就是 Puppeteer 的 Python 版本非官方實(shí)現(xiàn),它是一位來(lái)自于日本的工程師依據(jù) Puppeteer 的一些功能開(kāi)發(fā)出來(lái)的非官方版本
Pyppeteer 采用了 Python 的 async 機(jī)制,需要Python3.5 及以上版本才支持。
Pyppeteer能做什么但凡是需要通過(guò)Chrome瀏覽器手動(dòng)完成的操作都可以通過(guò) Pyppeteer 自動(dòng)完成,例如:
生成頁(yè)面截圖 生成PDF文件 抓取單頁(yè)面應(yīng)用并生成預(yù)先呈現(xiàn)的內(nèi)容 從網(wǎng)站抓取你需要的內(nèi)容 自動(dòng)表單提交,UI測(cè)試,鍵盤(pán)輸入等 截圖例如將頁(yè)面生成截圖可以直接調(diào)用 page.screenshot 方法
import asynciofrom 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())
截圖功能在海報(bào)分享等場(chǎng)景用的多,有看過(guò)有贊工程師分享的一篇文章,就有用到Puppeteer來(lái)做海報(bào)分享,性能比Canvas高。
而將網(wǎng)頁(yè)轉(zhuǎn)換為PDF的應(yīng)用場(chǎng)景更多,比如將網(wǎng)站博客、專(zhuān)欄,或者公眾號(hào)文章批量導(dǎo)出PDF,方便離線閱讀,比如我們最近做的一個(gè)醫(yī)療項(xiàng)目需要將用戶填寫(xiě)的資料支持PDF形式批量導(dǎo)出,就是用的Pyppeteer
導(dǎo)出PDF導(dǎo)出pdf直接調(diào)用page.pdf方法就可以, 代碼非常簡(jiǎn)潔
import asynciofrom 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())
接下來(lái)我們以公眾號(hào)文章為例,將html頁(yè)面制作成一個(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的開(kāi)源版本, 需要幾分鐘才能下載完
[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:UserslzjunAppDataLocalpyppeteerpyppeteerlocal-chromium575458
執(zhí)行完成后,我們來(lái)預(yù)覽下pdf文件
和原文鏈接對(duì)比,發(fā)現(xiàn)文章中的圖片丟失了。
通過(guò)分析,原來(lái)是頁(yè)面源代碼中,img 標(biāo)簽沒(méi)有src屬性,只有個(gè)data-src 屬性,默認(rèn)情況下圖片是無(wú)法正常顯示的,圖片之所有能在瀏覽器能正常展示出來(lái),是有個(gè)js腳本動(dòng)態(tài)地修改了dom元素為 <img src=’xxxx’>
這個(gè)網(wǎng)頁(yè)使用的是一種叫懶加載的技術(shù)展示圖片內(nèi)容,所謂懶加載就是圖片不會(huì)一次全部下載完,而是當(dāng)前瀏覽到什么位置,就加載該處的圖片,這樣能提高頁(yè)面的響應(yīng)速度,同時(shí)減輕服務(wù)器性能。
所以,我們也可以通過(guò)js代碼模擬真人瀏覽網(wǎng)頁(yè)一樣,滾動(dòng)鼠標(biāo),不停地往下滑動(dòng),將圖片動(dòng)態(tài)加載出來(lá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 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 代碼封裝成一個(gè)字符串當(dāng)作參數(shù)傳給 page.evaluate 函數(shù), 該代碼就是獲不斷滾動(dòng)頁(yè)面,直到頁(yè)面底部為止。這樣整個(gè)頁(yè)面的圖片就全部加載出來(lái)了。
效果看起來(lái)還不錯(cuò),和原頁(yè)面的樣式是一樣的
在Pyppeteer實(shí)踐應(yīng)用過(guò)程中,也遇到不少坑,最后都逐個(gè)解決了,這可以單獨(dú)寫(xiě)一篇文章,如果你在使用過(guò)程中遇到任何問(wèn)題歡迎與我交流
以上就是python基于pyppeteer制作PDF文件的詳細(xì)內(nèi)容,更多關(guān)于python pyppeteer制作PDF文件的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案2. 告別AJAX實(shí)現(xiàn)無(wú)刷新提交表單3. chat.asp聊天程序的編寫(xiě)方法4. 使用XSL將XML文檔中的CDATA注釋輸出為HTML文本5. ASP 信息提示函數(shù)并作返回或者轉(zhuǎn)向6. ASP錯(cuò)誤捕獲的幾種常規(guī)處理方式7. 小技巧處理div內(nèi)容溢出8. PHP循環(huán)與分支知識(shí)點(diǎn)梳理9. XML入門(mén)的常見(jiàn)問(wèn)題(一)10. css進(jìn)階學(xué)習(xí) 選擇符
