📸

Webサイトのスクリーンショットを自動化する方法

6 min read 3

Webサイトのスクリーンショットはブラウザの開発ツールや拡張機能を利用すれば手軽に行えます。しかし、あらかじめスクショしたいサイトやページが決まっていてかつ複数ページある場合では都度ページを開いて作業しているとそれなりに時間がかかります。

この記事ではそんな手動でのスクリーンショット作業を自動化させる方法を紹介します。
知らない単語が途中出てきても何ができるのかイメージだけつかんでもらえれば大丈夫です。

エンジニア以外の職種でも参考にできるよう細かい説明や難しい言葉は使わないようにしています。

実行環境の用意

今回スクリーンショットの自動化をPythonという言語で行います。「Pythonって何!?」という方は以下リンクの情報を軽く見ておいてもらえると多少理解が進むかと思います。

https://www.python.jp/pages/about.html

手元のローカルPCで今回やるような処理を実行するにはPython自体をインストールする必要があります。この記事ではそのような環境構築の手間を省くためGoogleが提供するColaboratoryと呼ばれるサービスを利用します。

https://colab.research.google.com/notebooks/intro.ipynb

Colaboratoryの利用方法は以下記事の一部を参照してみてください。ファイルの準備まで確認できればOKです。

https://zenn.dev/kazuki_tam/articles/23410c1a4fe91f661db9#colaboratoryとは

スクリーンショット自動化スクリプトの作成

Colaboratoryで新規ファイルの用意ができたら今回やりたいことの整理をしたいと思います。
最低限やりたいことは主に以下の3つです。

  • サイトURLを指定するだけでスクリーンショットを自動実行したい
  • 取得した画像を一括ダウンロードしたい
  • ウインドウサイズを指定してスクリーンショットを撮りたい

すぐに利用したい方はコピペで利用できるので「スクリーンショット自動化スクリプトの利用方法」から読み進めてください。

必要ファイルやライブラリの読み込み

Colaboratoryは標準で日本語フォントが入っていないようで、フォントを入れずに動かすと文字化けしてしまいます。(2021/03/28)

# 日本語フォントインストール
!apt-get -y install fonts-ipafont-gothic
!apt-get -y install fonts-ipafont-mincho

スクリーンショットの自動化スクリプトをすべて一からプログラムを書いていくとめちゃくちゃ時間がかかってしまうので、ライブラリと呼ばれる複雑な処理を抽象化して使いやすくしたプログラムを利用します。

https://ja.wikipedia.org/wiki/ライブラリ#:~:text=ライブラリ(英%3A library)は,コードの集まりと言える。

ブラウザ操作を自動化させるためSeleniumをインストールします。Seleniumはブラウザ操作を自動化させるのに必要なフレームワークです。

https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a
https://www.selenium.dev/
# seleniumインストール
!apt-get update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
!pip install selenium

# ライブラリインポート
from google.colab import files
import time
import shutil
import os

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Chromeヘッドレスモード起動
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',options=options)
driver.implicitly_wait(10)

ブラウザを裏側で起動させてスクリーンショットをとるためにHeadless Chromeを利用します。
Headless ChromeはブラウザーのUIを利用せずにブラウザ操作することを可能にします。
たとえば「Chromeを立ち上げてサイトにアクセスして・・・」といった作業をコマンドで指定できます。

https://developers.google.cn/web/updates/2017/04/headless-chrome?hl=ja

スクリーンショットを撮りたいサイトリストを以下のように記述します。

# 対象URL
urls = ['https://example.com', 'https://example.com/about/']

次に調整用の変数を定義しておきます。変数を定義しておくことで、ブラウザのウインドウサイズやファイル名を後から調整しやすくします。

ファイル名の接頭辞は fileNamePrefix で調整できます。screen とすると screen-1.png のように連番で保存されます。

ウインドウ幅375pxでスクリーショットを撮りたい場合は windowSizeWidth = 375 と指定します。ウインドウ幅を指定した場合、 screen-1200-1.png のようにサイズがファイル名に付与されます。

ウインドウの高さを指定したい場合も幅と同様です。
windowSizeHeight = 1000

ファイル名が被らないように連番を付与させるため番号の初期値を指定します。
shotNum = 0

# ファイル名接頭辞
fileNamePrefix = "screen"

# ウインドウ幅指定
# 初期値: False, スマホ: 375
windowSizeWidth = False
# windowSizeWidth = 1200

# ウインドウ高さ指定
# 初期値: False
windowSizeHeight = False
# windowSizeHeight = 1000

# 連番初期値
shotNum = 0

ダウンロードフォルダーの作成を以下の処理で行います。

# ダウンロードフォルダ作成
folderCheck = os.path.exists('screen-shot')
if folderCheck:
  shutil.rmtree('screen-shot')
os.mkdir('screen-shot')

urlsで定義したサイトにアクセスし、スクリーショットを撮る処理が以下に記述されています。
スクロールされてから要素が表示されるような表現に対応するため、わざとサイト下部までスクロールする処理を入れています。

# 繰り返し処理
for url in urls:
  # パス指定
  folderPath = 'screen-shot/' + fileNamePrefix + '-' + str(windowSizeWidth) + '-' if windowSizeWidth else 'screen-shot/' + fileNamePrefix + '-'

  # サイトURL取得
  driver.get(url)
  WebDriverWait(driver, 15).until(EC.presence_of_all_elements_located)
  
  # ウインドウ幅・高さ指定
  windowWidth = windowSizeWidth if windowSizeWidth else driver.execute_script('return document.body.scrollWidth;')
  windowHeight = windowSizeHeight if windowSizeHeight else driver.execute_script('return document.body.scrollHeight;')
  driver.set_window_size(windowWidth, windowHeight)

  # スクロール処理
  driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

  # 処理後一時待機
  time.sleep(3)

  # ファイル連番追加
  shotNum += 1
  shotNumStringified = str(shotNum)

  # スクリーンショット格納
  driver.save_screenshot(folderPath + shotNumStringified + '.png')

  # サーバー負荷軽減処理
  time.sleep(1)

# ブラウザ稼働終了
driver.quit()

最後に保存したスクリーンショットをzipファイルにまとめてダウンロードする処理を記述します。

# zipファイル変換ダウンロード
!zip -r download.zip screen-shot
files.download('download.zip')

以上でコードの記述は完了です。

スクリーンショット自動化スクリプトの利用方法

サイトURLを指定するだけでスクリーンショットを自動実行し、一括でファイルをダウンロードできます。次の完成スクリプトをそのままコピペして利用できます。すぐに利用したい方は対象URLだけ適宜調整してください。

処理の実行

処理を実行する際は赤枠の▷ボタンを押下してください。

ダウンロードファイルの管理

スクリーンショットされた画像ファイルはdownload.zipファイルに格納されます。
意図的に格納ファイルを削除してリセットしたい場合は左サイドバーの 🗂 アイコンを押下し、download.zipファイルを削除できます。

まとめ

アニメーションで画面が大きく変わるサイトではうまくスクリーンショットを取れないケースがあるかもしれません。そのような場合は処理のタイミングを遅らせてみるなど調整してみてください。
Web制作の現場ではスクリーンショットをとる作業がよくあるかと思います。今回紹介した内容が時間の効率化に繋がれば幸いです。

Discussion

yonemotoさま
記事拝見して、とても関心を持ちました。いきなりですが、薄謝ではありますがご提供させていただいたうえで、特定のサイト(観光予報プラットフォーム、公益社団日本観光振興協会)の向こう3か月の観光需要の予測画面を、約1週間おきにスクショし続けるプログラムを組んでいただくことは可能でしょうか?

コメントありがとうございます!この記事で紹介するColaboratoryは定期実行に対応していないため、記載いただいた要件ですと一からスクラッチで開発するより以下のようなサービスを使われるのが良いかと思います。

https://pashaco.app/

ご親切にありがとうございました。よく見てみます。

ログインするとコメントできます