Skip to content

Instantly share code, notes, and snippets.

@advanceboy
Last active March 10, 2023 19:31
Show Gist options
  • Save advanceboy/a8cb2baa37a75487b9ba4038b745c7d6 to your computer and use it in GitHub Desktop.
Save advanceboy/a8cb2baa37a75487b9ba4038b745c7d6 to your computer and use it in GitHub Desktop.
python selenium でページ全体のスクリーンショットを撮る
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This code provides the ability to take a screenshot of the entire page with Selenium WebDriver.
"""
import io
from time import sleep
from typing import List, Tuple, Optional
from PIL import Image
import selenium.webdriver
def get_full_screenshot_image(driver, reverse=False, driverss_contains_scrollbar=None):
# type: (selenium.webdriver.remote.webdriver.WebDriver, bool, Optional[bool]) -> Image.Image
"""
take full screenshot and get its Pillow instance
:param driver: Selenium WebDriver
:param reverse: Paste from bottom direction when combining images. The default is False.
:param driverss_contains_scrollbar: Set to True if the screenshot taken by WebDriver contains a horizontal scroll bar. Default is determined automatically.
"""
if driverss_contains_scrollbar is None:
driverss_contains_scrollbar = isinstance(driver, selenium.webdriver.Chrome)
# Scroll to the bottom of the page once
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(0.5)
scroll_height, document_client_width, document_client_height, inner_width, inner_height = driver.execute_script("return [document.body.scrollHeight, document.documentElement.clientWidth, document.documentElement.clientHeight, window.innerWidth, window.innerHeight]")
streams_to_be_closed = [] # type: List[io.BytesIO]
images = [] # type: List[Tuple[Image.Image, int]]
try:
# open
for y_coord in range(0, scroll_height, document_client_height):
driver.execute_script("window.scrollTo(0, arguments[0]);", y_coord)
stream = io.BytesIO(driver.get_screenshot_as_png())
streams_to_be_closed.append(stream)
img = Image.open(stream)
images.append((img, min(y_coord, scroll_height - inner_height))) # Image, y_coord
# load
scale = float(img.size[0]) / (inner_width if driverss_contains_scrollbar else document_client_width)
img_dst = Image.new(mode='RGBA', size=(int(document_client_width * scale), int(scroll_height * scale)))
for img, y_coord in (reversed(images) if reverse else images):
img_dst.paste(img, (0, int(y_coord * scale)))
return img_dst
finally:
# close
for stream in streams_to_be_closed:
stream.close()
for img, y_coord in images:
img.close()
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
[dev-packages]
pylint = "*"
mypy = "*"
[packages]
selenium = "*"
pillow = "*"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment