Python 打开 html 文件,截图,裁剪并另存为图片
Python open html file, take screenshot, crop and save as image
我正在使用 Bokeh 包生成地图以显示模拟结果。输出是具有交互性的 html 格式的独立地图。个别地图需要交互性。
查看此 link 示例:
http://docs.bokeh.org/en/0.10.0/docs/gallery/texas.html
模拟可以自动设置为 运行 多次,并且会为每次 运行 生成一张地图。这可能是 100 张地图。我希望能够将地图拼接在一起以制作电影 - 这不需要交互性。 Bokeh 具有通过浏览器创建 PNG 文件的功能,因此可以手动将每个地图保存为文件并使用 ffmpeg 创建电影。但是,如果您需要对 100 个文件执行此操作,则这不是一个真正的选项。目前没有办法通过 Bokeh 自动生成 PNG 文件,但我相信它会在某个时候添加。
所以我需要一个解决方法。我的想法是从存储在本地驱动器上的位置打开每个 html 文件,截屏,裁剪图像以保留所需的部分并保存。但我还没有找到有效的解决方案。
裁剪图像很容易:
from PIL import Image
img = Image.open(file_name)
box = (1, 1, 1000, 1000)
area = img.crop(box)
area.save('saved_image', 'jpeg')
我的问题是打开 html 文件并首先截取屏幕截图以提供给上述代码。
为此,我尝试了以下方法,但两者都需要 URL 而不是 html 文件。两者都使用对我不起作用的 Firefox,但我已经安装了 chrome 并适当地更改了代码。
How to take partial screenshot with Selenium WebDriver in python?
http://www.idiotinside.com/2015/10/20/take-screenshot-selenium-python/
我的代码是:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file_name')
driver.save_screenshot('image.png')
driver.quit()
哪个returns:
{"code":-32603,"message":"Cannot navigate to invalid URL"}
很明显,文件名不是 url,所以很清楚。如果您将它传递给一个网站,它就可以正常工作。任何帮助加载 html 和拍照的帮助将不胜感激!它不必涉及硒。
如果您 运行 Linux,则可能需要执行以下步骤。
首先在默认应用中通过command line打开html文件。你可能需要做类似
的事情
import os
os.system('command to open html file')
使用 solution listed 截屏。
然后按照提示在PIL中进行处理。
如果您在 windows、
中执行此操作
您可能需要设置 AutoIT 驱动程序,以便您可以使用 python 脚本来操作 GUI windows 等。
您可以使用 SimpleHTTPServer 创建一个基本的网络服务器并公开您的本地文件。
你应该 运行 在 html 是 python -m SimpleHTTPServer 8000
的路径中
然后把driver.get('file_name')
改成driver.get('localhost:8000/file_name.html')
我建议您使用 "wait until" 以确保在截屏之前所有内容都已加载:
driver.wait.until(EC.visibility_of_element_located((By.XPATH,'//*[@id="someID"]')))
hgazibara 评论被证明是最简单的修复。下面是一些简化的代码来提供答案。如果网页实际上不必为了要拍摄的屏幕截图而显示自己,那就太好了。以后看看能不能加上这个
import glob
from PIL import Image
from selenium import webdriver
# get a list of all the files to open
glob_folder = os.path.join(file_location, '*.html')
html_file_list = glob.glob(glob_folder)
index = 1
for html_file in html_file_list:
# get the name into the right format
temp_name = "file://" + html_file
# open in webpage
driver = webdriver.Chrome()
# The above line could be substituted for these 3 lines,
# which would prevent the webpage from opening first
###########
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(executable_path="C:\ChromeDriver\chromedriver.exe", chrome_options=options)
# Your path to your chromedriver could be different than mine
###########
driver.get(temp_name)
save_name = '00' + str(index) + '.png'
driver.save_screenshot(save_path, save_name))
driver.quit()
index += 1
# crop as required
img = Image.open(save_path, save_name))
box = (1, 1, 1000, 1000)
area = img.crop(box)
area.save('cropped_image' + str(index), 'png')
从 Bokeh 0.12.6
开始,现在可以更轻松地直接从 Python 截取这些屏幕截图,而无需打开浏览器。
导出的 PNG 看起来像这样
export_png(plot, filename="plot.png")
导出 SVG 看起来像这样
plot.output_backend = "svg"
export_svgs(plot, filename="plot.svg")
需要安装一些可选的依赖项。
您可以在 Exporting Plots section of the User Guide.
中找到更多信息
我正在使用 Bokeh 包生成地图以显示模拟结果。输出是具有交互性的 html 格式的独立地图。个别地图需要交互性。
查看此 link 示例:
http://docs.bokeh.org/en/0.10.0/docs/gallery/texas.html
模拟可以自动设置为 运行 多次,并且会为每次 运行 生成一张地图。这可能是 100 张地图。我希望能够将地图拼接在一起以制作电影 - 这不需要交互性。 Bokeh 具有通过浏览器创建 PNG 文件的功能,因此可以手动将每个地图保存为文件并使用 ffmpeg 创建电影。但是,如果您需要对 100 个文件执行此操作,则这不是一个真正的选项。目前没有办法通过 Bokeh 自动生成 PNG 文件,但我相信它会在某个时候添加。
所以我需要一个解决方法。我的想法是从存储在本地驱动器上的位置打开每个 html 文件,截屏,裁剪图像以保留所需的部分并保存。但我还没有找到有效的解决方案。
裁剪图像很容易:
from PIL import Image
img = Image.open(file_name)
box = (1, 1, 1000, 1000)
area = img.crop(box)
area.save('saved_image', 'jpeg')
我的问题是打开 html 文件并首先截取屏幕截图以提供给上述代码。
为此,我尝试了以下方法,但两者都需要 URL 而不是 html 文件。两者都使用对我不起作用的 Firefox,但我已经安装了 chrome 并适当地更改了代码。
How to take partial screenshot with Selenium WebDriver in python?
http://www.idiotinside.com/2015/10/20/take-screenshot-selenium-python/
我的代码是:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file_name')
driver.save_screenshot('image.png')
driver.quit()
哪个returns:
{"code":-32603,"message":"Cannot navigate to invalid URL"}
很明显,文件名不是 url,所以很清楚。如果您将它传递给一个网站,它就可以正常工作。任何帮助加载 html 和拍照的帮助将不胜感激!它不必涉及硒。
如果您 运行 Linux,则可能需要执行以下步骤。
首先在默认应用中通过command line打开html文件。你可能需要做类似
的事情import os
os.system('command to open html file')
使用 solution listed 截屏。
然后按照提示在PIL中进行处理。
如果您在 windows、
中执行此操作您可能需要设置 AutoIT 驱动程序,以便您可以使用 python 脚本来操作 GUI windows 等。
您可以使用 SimpleHTTPServer 创建一个基本的网络服务器并公开您的本地文件。
你应该 运行 在 html 是 python -m SimpleHTTPServer 8000
然后把driver.get('file_name')
改成driver.get('localhost:8000/file_name.html')
我建议您使用 "wait until" 以确保在截屏之前所有内容都已加载:
driver.wait.until(EC.visibility_of_element_located((By.XPATH,'//*[@id="someID"]')))
hgazibara 评论被证明是最简单的修复。下面是一些简化的代码来提供答案。如果网页实际上不必为了要拍摄的屏幕截图而显示自己,那就太好了。以后看看能不能加上这个
import glob
from PIL import Image
from selenium import webdriver
# get a list of all the files to open
glob_folder = os.path.join(file_location, '*.html')
html_file_list = glob.glob(glob_folder)
index = 1
for html_file in html_file_list:
# get the name into the right format
temp_name = "file://" + html_file
# open in webpage
driver = webdriver.Chrome()
# The above line could be substituted for these 3 lines,
# which would prevent the webpage from opening first
###########
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(executable_path="C:\ChromeDriver\chromedriver.exe", chrome_options=options)
# Your path to your chromedriver could be different than mine
###########
driver.get(temp_name)
save_name = '00' + str(index) + '.png'
driver.save_screenshot(save_path, save_name))
driver.quit()
index += 1
# crop as required
img = Image.open(save_path, save_name))
box = (1, 1, 1000, 1000)
area = img.crop(box)
area.save('cropped_image' + str(index), 'png')
从 Bokeh 0.12.6
开始,现在可以更轻松地直接从 Python 截取这些屏幕截图,而无需打开浏览器。
导出的 PNG 看起来像这样
export_png(plot, filename="plot.png")
导出 SVG 看起来像这样
plot.output_backend = "svg"
export_svgs(plot, filename="plot.svg")
需要安装一些可选的依赖项。 您可以在 Exporting Plots section of the User Guide.
中找到更多信息