【问题标题】:How to take a screenshot of an entire scroll element using Python如何使用 Python 截取整个滚动元素的屏幕截图
【发布时间】:2018-05-17 22:36:49
【问题描述】:

我需要截取整个网页的屏幕截图。这里的重要部分是我需要屏幕截图来包含屏幕上无法显示的页面的全部内容。

数据包含多行(行)数据,由于数据长度较长,所以有一个滚动条。每次的行数都不一样,截图应该有相应的依据。

对于滚动的长网页,执行此任务很简单。但是当数据很大并且在滚动条下时如何完成。

我想使用Python 完成此操作。我正在使用以下代码使用 Python 捕获网页的屏幕截图。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = webdriver.ChromeOptions()
options.add_argument('headless')
options.add_argument('window-size=1440x1440')
driver = webdriver.Chrome(executable_path=os.path.abspath('C:/Program Files (x86)/Python36/selenium/chromedriver/build/scripts-3.6/chromedriver.exe'),chrome_options=options)
driver.get("https://www.test.com") ##updated as a random test URL
time.sleep(60);
driver.save_screenshot('C:/Users/Dev/Desktop/Maxx/Snapshots/test.png')
driver.quit
print ("captured snapshot")

关于它在带有滚动条的浏览器上的外观数据。

【问题讨论】:

  • 继续滚动..不要忘记 selenium 只是一个浏览器模拟器driver.execute_script("window.scrollTo(0,{0})".format(scrollHeight))
  • 问题中的截图只是网页的一部分。网页的前半部分包含一些图表,网页的下半部分包含包含与这些图表相关的数据的表格。
  • @user1767754 尝试使用您提到的命令,仍然看到快照中的滚动条,而不是完整的数据列表。
  • 这可能是你最小的问题......你可以覆盖 css 或只使用 opencv 裁剪这部分

标签: python selenium-webdriver screenshot


【解决方案1】:
from PIL import Image
from io import BytesIO

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def open_url(url):
    options = Options()

    options.headless = True

    driver = webdriver.Chrome(chrome_options=options)

    driver.maximize_window()
    driver.get(url)
    save_screenshot(driver, 'screen.png')

def save_screenshot(driver, file_name):
    height, width = scroll_down(driver)
    driver.set_window_size(width, height)
    img_binary = driver.get_screenshot_as_png()
    img = Image.open(BytesIO(img_binary))
    img.save(file_name)
    # print(file_name)
    print(" screenshot saved ")


def scroll_down(driver):
    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")

    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

            rectangles.append((ii, i, top_width, top_height))

            ii = ii + viewport_width

        i = i + viewport_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]))
            time.sleep(0.5)
        # time.sleep(0.2)

        if rectangle[1] + viewport_height > total_height:
            offset = (rectangle[0], total_height - viewport_height)
        else:
            offset = (rectangle[0], rectangle[1])

        previous = rectangle

    return (total_height, total_width)

open_url("https://www.medium.com")

scroll_down函数滚动到页面底部并返回网页的总高度和宽度。

save_screenshot函数设置窗口大小并使用枕头保存屏幕截图。

【讨论】:

  • 我猜它适用于页面并向下滚动以获得总高度和宽度,对于 iframe,我们需要根据它进行更改。如果您可以提供您尝试截取屏幕截图的那种类型的示例,这可能有助于给出正确的解释?
  • 当然。如果您访问此页面:sampleIframe,您将看到 iframe,您还会看到滚动条。我尝试了很多代码,但仍然没有代码能够通过滚动它来截取 iframe 的完整屏幕截图。所有代码截图如下:screenshot
  • 很好的解决方案。你知道我可以如何将此代码用于受密码保护的网站吗?
  • 是的,我们可以先登录网站再使用,稍后我会添加sn-p来截图密码保护
猜你喜欢
  • 2016-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 2021-05-10
  • 2021-04-16
相关资源
最近更新 更多