我们都知道一个正常的网页,是由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
的文件,那就是我们导出的图片文件!
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"!
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~~~