Python将html文件转为图片

发布时间:2021-12-03 公开文章

背景

在上一期玩转Echarts5中,留了一个问题:将html转为图片。周末亲测,发现cancas可以提取并保存,但是<DIV>块中的背景图片缺没有办法再拼接保存,尤其是LBS可视化。

于是,本主再次基础重器selenium。

代码

import base64
import os
import time

from selenium import webdriver
from selenium.common.exceptions import WebDriverException
 
options = webdriver.ChromeOptions()
#options.add_argument('--headless') # Chrome最新驱动无效,可以使用firefox或phantomjs
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('window-size=1920x1080')



path = os.getcwd().replace("\\", "/")
full_path = path+'/templates/test_flask_render.html'


try:
    driver = webdriver.Chrome(options=options)
    driver.maximize_window()
    driver.get(f'file:///{full_path}')
    time.sleep(3)
    driver.get_screenshot_as_file('./images/test-canvas.png')
    driver.quit()
    print("截图成功")
except WebDriverException:
    print("截图失败")

 

这玩意有几个弊端:

1.selenium新版本已经不支持谷歌浏览器的无头模式。

2.预设浏览器窗口大小,仅截取窗口内的内容。

3.渲染图片需要时间,所以截图需要延迟3s。

全部页面

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()

参考:【Python】Python将HTML转成图片、PDF_随波一落叶-CSDN博客

结语

最早本主使用腾讯地图的API,实现热点图等。最近在尝试使用Bokeh联合Echarts5实现地理位置可视化的交互。