【Python】Python将HTML转成图片、PDF

一、方法一——imgkit库

1、安装python的imgkit、pdfkit库

pip install imgkit
pip install pdfkit

2、下载wkhtmltopdf工具包

下载地址:https://wkhtmltopdf.org/downloads.html ,64位windows的话可以下载红框标出的版本

这个工具包有两个程序,分别用来转图片和pdf:

3、使用

1)转为pdf

API说明

我们常用PDFKit的三个API:

  • from_url:将远程URL页面导出为PDF。
  • from_file:将HTML文件导出为PDF。
  • from_string:将字符串导出为PDF。
import pdfkit

path_wkpdf = r'D:\DevelopSoftware\wkhtmltopdf\bin\wkhtmltopdf.exe'  # 工具路径
cfg = pdfkit.configuration(wkhtmltopdf=path_wkpdf)

# 1、将html文件转为pdf
pdfkit.from_file(r'./helloworld.html', 'helloworld.pdf', configuration=cfg)
pdfkit.from_file([r'./helloworld.html', r'./111.html', r'./222.html'], 'helloworld.pdf', configuration=cfg)  # 传入列表

# 2、从url获取html,再转为pdf
pdfkit.from_url('https://httpbin.org/ip', 'ip.pdf', configuration=cfg)
pdfkit.from_url(['https://httpbin.org/ip','https://httpbin.org/ip'], 'ip.pdf', configuration=cfg)  # 传入列表

# 3、将字符串转为pdf
pdfkit.from_string('Hello!','hello.pdf', configuration=cfg)

2)转为图片

import imgkit

path_wkimg = r'D:\DevelopSoftware\wkhtmltopdf\bin\wkhtmltoimage.exe'  # 工具路径
cfg = imgkit.config(wkhtmltoimage=path_wkimg)
# 1、将html文件转为图片
imgkit.from_file(r'./helloworld.html', 'helloworld.jpg', config=cfg)
# 2、从url获取html,再转为图片
imgkit.from_url('https://httpbin.org/ip', 'ip.jpg', config=cfg)
# 3、将字符串转为图片
imgkit.from_string('Hello!','hello.jpg', config=cfg)

3)补充options选项

评论区有大胸弟问中文字符串乱码的问题(参考:https://www.cnblogs.com/Neeo/articles/11566980.html):

一般情况下,html中的meta中表明编码格式charset时,程序就会自动按照charset编码进行转码。但如果未标明就会出现问题,因此可以通过在options参数中设置编码选项:

options = {
    "encoding": "UTF-8",  # 设置编码格式,这边utf8是个示例,具体用哪个编码还要看你的html文件用什么
    'javascript-delay': '2000',  # 设置等待javascript渲染时间
    "custom-header": [('Accept-Encoding', 'gzip')],  # 下面的是设置图片的样式
    'page-size': 'Letter',
    'margin-top': '0.75in',
    'margin-right': '0.75in',
    'margin-bottom': '0.75in',
    'margin-left': '0.75in',
    'no-outline': False
}

其他options可以参考:https://zhuanlan.zhihu.com/p/37096502

 编码问题实例:

import imgkit

path_wkimg = r'D:\DevelopSoftware\wkhtmltopdf\bin\wkhtmltoimage.exe'  # 工具路径
cfg = imgkit.config(wkhtmltoimage=path_wkimg)
options = {
    "encoding": "UTF-8"        # 这个具体要看你那个html页面到底是以什么编码格式保存的
}
imgkit.from_file(r'./helloworld.html', 'helloworld.jpg', options=options, config=cfg)

二、将html转为图片方法二——selenium

通过selenium模拟浏览器访问页面,再将页面保存为图片。

from selenium import webdriver
from selenium.common.exceptions import WebDriverException

options = webdriver.ChromeOptions()
#options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('window-size=1920x1080')


try:
    driver = webdriver.Chrome(options=options)
    driver.maximize_window()
    driver.get("https://www.baidu.com")
    driver.get_screenshot_as_file("baidu.png")
    driver.quit()
except WebDriverException:
    print("截图失败")

不过上面这个只能截显示器显示部分的页面,如果要截整个网页,我在网上找到了一份代码:

from selenium import webdriver
import time
import os.path
import multiprocessing as mp


def webshot(tup):
    print("当前进程%d已启动" %os.getpid())

    options = webdriver.ChromeOptions()
    options.add_argument('--headless')  # 不知为啥只能在无头模式执行才能截全屏
    options.add_argument('--disable-gpu')
    driver = webdriver.Chrome(options=options)
    driver.maximize_window()
    # 返回网页的高度的js代码
    js_height = "return document.body.clientHeight"
    picname = str(tup[0])
    link = tup[1]
    print(link)

    try:
        driver.get(link)
        k = 1
        height = driver.execute_script(js_height)
        while True:
            if k * 500 < height:
                js_move = "window.scrollTo(0,{})".format(k * 500)
                print(js_move)
                driver.execute_script(js_move)
                time.sleep(0.2)
                height = driver.execute_script(js_height)
                k += 1
            else:
                break
        scroll_width = driver.execute_script('return document.body.parentNode.scrollWidth')
        scroll_height = driver.execute_script('return document.body.parentNode.scrollHeight')
        driver.set_window_size(scroll_width, scroll_height)
        driver.get_screenshot_as_file("D:/pics/" + picname)
        print("Process {} get one pic !!!".format(os.getpid()))
        driver.quit()
    except Exception as e:
        print(picname, e)


if __name__ == '__main__':
    # 首先创建一个保存截图的文件夹
    filename = "D:/pics/"
    if not os.path.isdir(filename):
        # 判断文件夹是否存在,如果不存在就创建一个
        os.makedirs(filename)

    # 读取保存url的文件,返回一个列表
    # 列表中每个元素都是一个元组,文件保存url的格式是:保存为图片的名称, 网页地址。
    # 例:baidu.png,https://www.baidu.com
    #     zhihu.png,https://www.zhihu.com
    with open('urls.txt', 'r') as f:
        lines = f.readlines()
    urls = []
    for line in lines:
        thelist = line.strip().split(",")
        if len(thelist) == 2 and thelist[0] and thelist[1]:
            urls.append((thelist[0], thelist[1]))

    # 创建进程池来多进程执行
    pool = mp.Pool()
    pool.map_async(func=webshot, iterable=urls)
    pool.close()
    pool.join()

ok,如果还有啥问题可以评论区问我,我看到会回复~~

  • 20
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值