LoginSignup
2
4

More than 1 year has passed since last update.

Seleniumで全画面スクリーンショット(Python)

Last updated at Posted at 2021-05-29

はじめに

調べていてちょっとハマったのでここに書き残しておくことに。

調査報告

大別して2種類の方法を目にした。

  1. スクロールしながらスクショしていき、最後にPillowライブラリで結合する。(参考)
  2. ウィンドウサイズを拡大して1枚のスクショに収める。(参考)

基本的には2番目の方法でいいと思われるが、あまりに領域が広い場合メモリが足りなくなるおそれがあるため、その場合は1番目の方法を採用すればいいと思われる。

結論

基本的には以下の関数を用いる。(2番目の方法)

def fullpage_screenshot(driver, file):
    w = driver.execute_script("return document.body.parentNode.scrollWidth")
    h = driver.execute_script("return document.body.parentNode.scrollHeight")
    driver.set_window_size(w, h)
    driver.save_screenshot(file)

領域が広い場合は以下の関数を用いるべきかもしれない。(1番目の方法, コピペ)

from PIL import Image
import time

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
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4