【发布时间】:2017-06-02 23:14:11
【问题描述】:
在尝试了各种方法之后......我偶然发现了这个页面,用 chromedriver、selenium 和 python 截取了整页截图。
原代码为here。 (我复制下面这篇文章中的代码)
它使用 PIL 并且效果很好!但是,有一个问题......它会捕获固定的标题并在整个页面中重复,并且在页面更改期间还会丢失页面的某些部分。截图示例网址:
http://www.w3schools.com/js/default.asp
如何避免使用此代码重复标头...或者有没有更好的选择只使用 python... (我不知道 java 也不想使用 java)。
请看下面当前结果的截图和示例代码。
test.py
"""
This script uses a simplified version of the one here:
https://snipt.net/restrada/python-selenium-workaround-for-full-page-screenshot-using-chromedriver-2x/
It contains the *crucial* correction added in the comments by Jason Coutu.
"""
import sys
from selenium import webdriver
import unittest
import util
class Test(unittest.TestCase):
""" Demonstration: Get Chrome to generate fullscreen screenshot """
def setUp(self):
self.driver = webdriver.Chrome()
def tearDown(self):
self.driver.quit()
def test_fullpage_screenshot(self):
''' Generate document-height screenshot '''
#url = "http://effbot.org/imagingbook/introduction.htm"
url = "http://www.w3schools.com/js/default.asp"
self.driver.get(url)
util.fullpage_screenshot(self.driver, "test.png")
if __name__ == "__main__":
unittest.main(argv=[sys.argv[0]])
util.py
import os
import time
from PIL import Image
def fullpage_screenshot(driver, file):
print("Starting chrome full page screenshot workaround ...")
total_width = driver.execute_script("return document.body.offsetWidth")
total_height = driver.execute_script("return document.body.parentNode.scrollHeight")
viewport_width = driver.execute_script("return document.body.clientWidth")
viewport_height = driver.execute_script("return window.innerHeight")
print("Total: ({0}, {1}), Viewport: ({2},{3})".format(total_width, total_height,viewport_width,viewport_height))
rectangles = []
i = 0
while i < total_height:
ii = 0
top_height = i + viewport_height
if top_height > total_height:
top_height = total_height
while ii < total_width:
top_width = ii + viewport_width
if top_width > total_width:
top_width = total_width
print("Appending rectangle ({0},{1},{2},{3})".format(ii, i, top_width, top_height))
rectangles.append((ii, i, top_width,top_height))
ii = ii + viewport_width
i = i + viewport_height
stitched_image = Image.new('RGB', (total_width, total_height))
previous = None
part = 0
for rectangle in rectangles:
if not previous is None:
driver.execute_script("window.scrollTo({0}, {1})".format(rectangle[0], rectangle[1]))
print("Scrolled To ({0},{1})".format(rectangle[0], rectangle[1]))
time.sleep(0.2)
file_name = "part_{0}.png".format(part)
print("Capturing {0} ...".format(file_name))
driver.get_screenshot_as_file(file_name)
screenshot = Image.open(file_name)
if rectangle[1] + viewport_height > total_height:
offset = (rectangle[0], total_height - viewport_height)
else:
offset = (rectangle[0], rectangle[1])
print("Adding to stitched image with offset ({0}, {1})".format(offset[0],offset[1]))
stitched_image.paste(screenshot, offset)
del screenshot
os.remove(file_name)
part = part + 1
previous = rectangle
stitched_image.save(file)
print("Finishing chrome full page screenshot workaround...")
return True
【问题讨论】:
-
我正在截取需要多次滚动/拼接的页面。不幸的是,它不是公共 URL(只有登录后才能看到该页面)。你知道为什么它也一直附加标题吗? res.cloudinary.com/mpyr-com/image/upload/v1551372542/…
-
我现在已将答案更改为@lizesong1988(如下)并将最长高度设置为 8000 像素。最长元素的 ele xpath 总是返回 1100px 左右的值,这不是很好。所以我只是硬编码为 8000。这对我来说是最好和最简单的答案。
-
@ihightower 感谢您编写了很棒的代码。我面临同样的问题。是否有可能让相同的代码也适用于 div?就我而言,滚动条存在于 div 上。
-
现在最简单的答案是使用
playwright,请参阅下面接受的答案以及最新的更新信息。 @DeepakKumar
标签: python selenium selenium-chromedriver webpage-screenshot