Seleniumを使ってPythonでスクリーンショットを取得する

Seleniumを使ってPythonでスクリーンショットを取得する プログラミング

「ブラウザで見たままのスクリーンショットが欲しい」

このシンプルな要望に応えるのは、Seleniumです。
もちろん、文字化けや文字フォントの問題とは無縁です。

本記事では、キレイなスクリーンショットを取得する方法を解説します。
コピペで使えるコードも載せています。

本記事の内容

  • Seleniumを準備する
  • PythonでAmazonのスクリーンショットを取得する
  • PythonでTwitterのスクリーンショットを取得する

それでは、上記に沿って解説していきます。

Seleniumを準備する

Pythonでスクリーンショットを撮るには、Seleniumを利用します。
そのため、Seleniumを利用できることが前提となります。

Seleniumのインストールに関しては、次の記事をご覧ください。

以上、Seleniumの準備について説明しました。
次は、スクリーンショットを撮っていきます。

PythonでAmazonトップのスクリーンショットを取得する

このスクリーンショットは、次のコードで取得しています。

screenshot_1.py

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

CHROMEDRIVER = "chromedriver.exeのパス"
URL = "https://www.amazon.co.jp/"

options = Options()
# スクロールバーを非表示にする
options.add_argument('--hide-scrollbars')
# シークレットモードでChromeを起動する
options.add_argument('--incognito')
# ブラウザを表示しない
options.add_argument('--headless')

driver = webdriver.Chrome(CHROMEDRIVER, options=options)

# ウィンドウサイズ=画像サイズ
driver.set_window_size(1024, 768)
# 対象ページへアクセス
driver.get(URL)
# スクリーンショットを取得
driver.save_screenshot('result.png')

driver.quit()

次の箇所が理解できない場合は、上記で紹介した記事をご覧ください。

CHROMEDRIVER = "chromedriver.exeのパス"

プログラムの内容は、コメントで確認してください。
できる限りでコメントをつけています。

どうでしょうか?
なんてことないですよね。

でも、このコードだとスクリーンショットを取得できないケースがあります。
次は、そのケースについて確認しましょう。

PythonでTwitterのスクリーンショットを取得する

先ほどのプログラム(screenshot_1.py)における「URL」の値を変更します。

URL = "https://twitter.com/AmazonJP"

そのように変更して取得したスクリーンショットが、上の画像となります。
なぜ、このような空っぽの画面になるのでしょうか?

その理由は、タイミングにあります。

Twitterは、Ajaxにより動的にコンテンツを表示しています。
そのため、コンテンツが表示し終わるまでにしばらく時間がかかります。

screenshot_1.pyのプログラムでは、Ajax処理の途中でスクリーンショットを撮るのです。
だから、空っぽの画面のスクリーンショットを取得することになります。

このタイミングの問題を解決したコードは、以下。

screenshot_2.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException

CHROMEDRIVER = "chromedriver.exeのパス"
URL = "https://twitter.com/AmazonJP"

options = Options()
options.add_argument('--hide-scrollbars')
options.add_argument('--incognito')
options.add_argument('--headless')

driver = webdriver.Chrome(CHROMEDRIVER, options=options)

driver.set_window_size(1024, 768)
# 暗黙的に指定時間待つ(秒)
driver.implicitly_wait(10)
driver.get(URL)

try:
    # articleタグを探す
    element = driver.find_element_by_tag_name("article")
except NoSuchElementException:
    print("探した要素は存在しない")
finally:
    driver.save_screenshot('result.png')
    driver.quit()

この変更したプログラムを実行すると、次のスクリーンショットを取得できます。

追記した箇所には、コメントをつけています。
ポイントは、以下の部分です。

# 暗黙的に指定時間待つ(秒)
driver.implicitly_wait(10)
    # articleタグを探す
    element = driver.find_element_by_tag_name("article")

これらは、二つで一つです。
セットで使うと覚えておいてください。
find_element_by_tag_nameに限らず、find_element_〇が対象となります。

機能としては、implicitly_waitに指定した時間だけ要素を探します。
要素が見つかった時点で、次の処理へ進みます。

もし見つからなかったら、エラーとなります。
エラーになるのは嫌なので、例外処理を対応しています。

また、implicitly_waitを設定するだけでは待機しません。
find_element_〇を実行することにより、最大で10秒間は探します。
調査した限りでは、2秒以内にはarticleタグが見つかっています。

なお、articleタグは以下の要素になります。

articleタグが見つかった時点で、コンテンツ表示は完了しているとみなしています。
仮にarticleタグが見つからなかった場合、10秒間は待機することになります。

10秒経てば、さすがにコンテンツ表示は完了しています。
だから、見つかる・見つからないに関わらず、スクリーンショットは上手く撮れます。

ただし、見つからない場合は10秒間待たないといけません。
まあ、10秒ぐらいはデフォルトで待機するのもアリとは思いますけどね。

以上、PythonでTwitterのスクリーンショットを取得するための説明でした。

追記 2021年11月29日
この記事は、Selenium 3を利用した場合の内容となります。
Selenium 4の場合は、次の記事を参考にしてみてください。

タイトルとURLをコピーしました