取得イメージ
①表示されている箇所のみスクリーンショットを取るパターン
(スクロールで隠れている箇所は隠れたまま)
②スクロールで隠れた箇所も含めてスクリーンショットを取るパターン
(すごい縦長のページの場合、すごい縦長の画像になります)
どちらも対応できる処理を作ります。
環境
windows10
Python 3.11.4
Selenium 4.10.0
Chrome 114.0.5735.134
※Chrome DevTools Protocolの機能を利用するためChrome専用です。
スクリーンショット取得処理
以下のようにするとスクリーンショットを取得できます。
import base64
from selenium import webdriver
def save_screenshot(driver, file_path, is_full_size=False):
# スクリーンショット設定
screenshot_config = {
# Trueの場合スクロールで隠れている箇所も含める、Falseの場合表示されている箇所のみ
"captureBeyondViewport": is_full_size,
}
# スクリーンショット取得
base64_image = driver.execute_cdp_cmd("Page.captureScreenshot", screenshot_config)
# ファイル書き出し
with open(file_path, "wb") as fh:
fh.write(base64.urlsafe_b64decode(base64_image["data"]))
# driver生成
driver = webdriver.Chrome()
# ウィンドウ最大化
driver.maximize_window()
# サイト表示
driver.get("https://pypi.org")
# 見えている箇所のみのスクリーンショット取得 取得イメージ①
save_screenshot(driver, "not_full_size.png")
# 全画面スクリーンショット取得 取得イメージ②
save_screenshot(driver, "full_size.png", is_full_size=True)
解説
スクリーンショットパラメーター
Chrome DevTools Protocol(CDP) の機能でスクリーンショットを取っており
その際に、「全画面」にするか「見えている範囲のみ」にするかを指定しています。
パラメーターはCDPのドキュメントを参照
重要なのはcaptureBeyondViewport
とfromSurface
の2つのパラメーターです。
どちらもTrue
になっていないと表示されている箇所のみのスクリーンショットになります。
fromSurface
はデフォルト値がTrue
になっているので指定せず
captureBeyondViewport
を変更し
True: 全画面
False: 見えている範囲のみ
を切り替えています。
screenshot_config = {
# Trueの場合スクロールで隠れている箇所も含める、Falseの場合表示されている箇所のみ
"captureBeyondViewport": is_full_size,
}
スクリーンショット取得関数
「保存するファイルのパス」と「全画面で取得するか」を引数に渡して呼び出せるよう関数化しています。
save_screenshot(driver, file_path, is_full_size=False)
is_full_size
(全画面で取得するか)は初期値をFalse(見えている範囲のみ)にしているので
全画面で取得したい場合はTrue
を指定して呼び出します。
save_screenshot(driver, "full_size.png", is_full_size=True)
# is_full_sizeを指定しないとデフォルトでFalseになる
save_screenshot(driver, "not_full_size.png")
# または明示的に指定することも可
save_screenshot(driver, "not_full_size.png", is_full_size=False)
file_path
は絶対パス、相対パスどちらでも指定できます。
例えば以下のようにすると、screenshotというフォルダの中に保存できます。
(フォルダが存在しないとエラーになるので、事前に作成)
save_screenshot(driver, "screenshot/test.png")
以上で「見えている範囲のスクリーンショットをとる」「全画面のスクリーンショットをとる」ことができました。
以降は、スクリーンショットの取得位置・範囲を指定する方法です。
(位置を指定する)
パラメーターclip
で位置を明示的に指定することができます。
# 画面サイズの取得
page_rect = driver.execute_cdp_cmd("Page.getLayoutMetrics", {})
# スクリーンショット設定、全画面取得されるよう設定
screenshot_config = {
"captureBeyondViewport": True,
"clip": {
"width": page_rect["contentSize"]["width"],
"height": page_rect["contentSize"]["height"],
"x": 0,
"y": 0,
"scale": 1,
},
}
# スクリーンショット取得
base64_image = driver.execute_cdp_cmd("Page.captureScreenshot", screenshot_config)
width
: 画面幅
height
: 画面高さ
x
: 横位置
y
: 縦位置
scale
: ページの縮尺
を指定することができます。
以下のように設定すると、右に200pxずらし、縮尺30%でスクリーンショットできます。
screenshot_config = {
"captureBeyondViewport": True,
"clip": {
"width": page_rect["contentSize"]["width"],
"height": page_rect["contentSize"]["height"],
"x": 200,
"y": 0,
"scale": 0.3,
},
}
参考