pip install imgkit
pip install pdfkit
下载地址:https://wkhtmltopdf.org/downloads.html ,64位windows的话可以下载红框标出的版本
这个工具包有两个程序,分别用来转图片和pdf:
API说明
我们常用PDFKit的三个API:
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)
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)
评论区有大胸弟问中文字符串乱码的问题(参考: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)
通过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,如果还有啥问题可以评论区问我,我看到会回复~~