LoginSignup
4
4

取得イメージ

①表示されている箇所のみスクリーンショットを取るパターン
(スクロールで隠れている箇所は隠れたまま)
スクロール.png

②スクロールで隠れた箇所も含めてスクリーンショットを取るパターン
(すごい縦長のページの場合、すごい縦長の画像になります)
どちらも対応できる処理を作ります。
test.png

環境

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のドキュメントを参照

重要なのはcaptureBeyondViewportfromSurfaceの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,
    },
}

test.png

参考

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