我們都知道一個正常的網頁,是由html+css+js組成,而其本質是一段段代碼編寫編譯而來的。而圖片是由一堆二進制數據組成的,我們該如何將網頁上顯示的內容導出爲我們想要的圖片或者pdf呢?博主閒極無聊逛遍github,發現了一個有趣的庫pyppeteer
,它實現了我所需要導出需求。接下來我們來看看它是怎麼操作的:
安裝所需要的庫
pip install pillow
pip install reportlab
pip install pyppeteer
導出爲圖片
import os
import asyncio
from pyppeteer import launch
async def save_image(url, img_path):
"""
導出圖片
:param url: 在線網頁的url
:param img_path: 圖片存放位置
:return:
"""
browser = await launch()
page = await browser.newPage()
# 加載指定的網頁url
await page.goto(url)
# 設置網頁顯示尺寸
await page.setViewport({'width': 1920, 'height': 1080})
'''
path: 圖片存放位置
clip: 位置與圖片尺寸信息
x: 網頁截圖的x座標
y: 網頁截圖的y座標
width: 圖片寬度
height: 圖片高度
'''
await page.screenshot({'path': img_path, 'clip': {'x': 457, 'y': 70, 'width': 730, 'height': 2600}})
await browser.close()
if __name__ == '__main__':
url = "https://www.jianshu.com/p/13dadc463f40"
img_path = os.path.join(os.getcwd(), "example.png")
loop = asyncio.get_event_loop()
loop.run_until_complete(save_image(url, img_path))
執行完畢之後,不出意外的情況下,將會在當前目錄下生成一個名爲example.png
的文件,那就是我們導出的圖片文件!
整頁導出爲pdf
import os
import asyncio
from pyppeteer import launch
async def save_pdf(url, pdf_path):
"""
導出pdf
:param url: 在線網頁的url
:param pdf_path: pdf存放位置
:return:
"""
browser = await launch()
page = await browser.newPage()
# 加載指定的網頁url
await page.goto(url)
# 設置網頁顯示尺寸
await page.setViewport({'width': 1920, 'height': 1080})
'''
path: 圖片存放位置
width: 紙張寬度,帶單位的字符串
height: 紙張高度,帶單位的字符串
'''
await page.pdf({'path': pdf_path, 'width': '730px', 'height': '2600px'})
await browser.close()
if __name__ == '__main__':
url = "https://www.jianshu.com/p/13dadc463f40"
pdf_path = os.path.join(os.getcwd(), "example.pdf")
loop = asyncio.get_event_loop()
loop.run_until_complete(save_pdf(url, pdf_path))
執行完畢之後,不出意外的情況下,將會在當前目錄下生成一個名爲example.pdf
的文件,那就是我們導出的pdf文件!不過這種導出有一種弊端,它是將整個網頁導出爲pdf,無法像圖片那樣支持位置參數,可以截取部分區域進行導出!因此,我對代碼進行修改了一下,請看下面的"區域導出爲pdf"!
區域導出爲pdf
import os
import asyncio
from io import BytesIO
from PIL import Image
from pyppeteer import launch
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.utils import ImageReader
async def save_pdf(url, pdf_path):
"""
導出pdf
:param url: 在線網頁的url
:param pdf_path: pdf存放位置
:return:
"""
browser = await launch()
page = await browser.newPage()
# 加載指定的網頁url
await page.goto(url)
# 設置網頁顯示尺寸
await page.setViewport({'width': 1920, 'height': 1080})
'''
clip: 位置與圖片尺寸信息
x: 網頁截圖的x座標
y: 網頁截圖的y座標
width: 圖片寬度
height: 圖片高度
'''
img_data = await page.screenshot({'clip': {'x': 457, 'y': 70, 'width': 730, 'height': 2600}})
im = Image.open(BytesIO(img_data))
page_width, page_height = im.size
c = Canvas(pdf_path, pagesize=(page_width, page_height))
c.drawImage(ImageReader(im), 0, 0)
c.save()
if __name__ == '__main__':
url = "https://www.jianshu.com/p/13dadc463f40"
pdf_path = os.path.join(os.getcwd(), "example.pdf")
loop = asyncio.get_event_loop()
loop.run_until_complete(save_pdf(url, pdf_path))
如此,我們就可以進行區域截取導出pdf文件了!
值得注意的時,由於網絡、配置以及一切不可控因素,上面幾種方法都會有一定程度的出現導出錯誤,所以建議加上重試機制!
更多pyppeteer
操作請看:https://github.com/miyakogi/pyppeteer
自此,Over~~~