🚀

MacでWeb画面のスクリーンショットを自動で撮り続けたい

2023/04/05に公開

やりたいこと

  • Webの画面を1時間ごと、1分ごとなど指定してキャプチャしたい
    • 画面は最小化してもOK
  • Macを使う

やったこと(書いていること)

  • shell scriptの作成
  • launchdの準備
    • LaunchControlを使う
  • ハマったこと、確認事項

書いていないこと

  • 各機能の詳細な説明
  • これがベストプラクティス、というニュアンス
  • 画面を開き続ける方法

準備

  • Mac
    • OSをCatalina→Venturaにアップデート(Catalinaだと設定で詰まったので)
    • Safari

shell scriptの作成

  • Windowを指定する場合は、対象をSafariにする。Chromeは動かなかった
    • 画面の場所で指定する場合は、何でもよい
  • capture_screenというディレクトリに、20230404-194315.png(2023/04/04 19時43分15秒)のような形式で保存する
  • osascript -e 'tell application "Safari"...という部分がウィンドウIDを取得するところなのですが、Chromeだとできなかったので、Safariにしています
capture_screen.sh
#!/bin/bash

output_dir="/full/path/capture_screen/"
output_file="${output_dir}$(date +%Y%m%d-%H%M%S).png"

# -x: No sound
# -l: Set the window ID
screencapture -x -l $(osascript -e 'tell application "Safari" to get id of front window' | awk '{printf "%.0f\n", $1}') "$output_file"

launchdを使う

  • macOS Mojave(10.14)以降はセキュリティの関係でcronが使いづらくなり、代わりにlaunchdを使うとのこと(知りませんでした・・・)

  • xmlの設定

    • ~/Library/LaunchAgents/に以下ファイルを置く
    • ※ファイル名のyourusernameを自分のMacのusernameにする。
com.yourusername.screencapture.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.yourusername.screencapture</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/your/script.sh</string>
    </array>
    <key>StartInterval</key>
    <integer>3600</integer>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/tmp/com.yourusername.screencapture.err</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.yourusername.screencapture.out</string>
</dict>
</plist>

変更する点

  • <string>com.yourusername.screencapture</string> のところを、スクリプトのパスに /path/to/your/script.sh
  • <integer>3600</integer>のところはインターバル(秒)
  • (StandardErrorPath, StandardOutPathは、変更しなくてもよいです。ログは動作確認で有用なので cat等で見るかGUIで見ます)

ターミナルから操作

(LaunchControl GUIを使うならここは飛ばしてよい)

※yourusernameを自分のusernameにする

ロード

launchctl load ~/Library/LaunchAgents/com.yourusername.screencapture.plist

(デフォルトではロード時にスクリプト実行)

ステータスを確認

launchctl list | grep com.yourusername.screencapture

この結果、2番めの数字がエラーコードなので0なら正常

  • 78はパーミッションエラーでした
  • 126はDesktop/にアクセスできないエラーでした

アンロード

launchctl unload ~/Library/LaunchAgents/com.yourusername.screencapture.plist

GUIから操作

LaunchControlをインストール

brew install launchcontrol

GUIで設定確認できて便利です(下図)。load, unloadはできますが、xmlの更新は上手くできなかったのでファイル側から変更していました。

  • 画面が緑文字になっていたら設定はOK
  • 上の囲んでいる部分がLoad/Unloadボタン
  • デフォルトではロード時にスクリプト実行
  • 右の囲んでいるところでTRCを押すとログが見れる

(参考:LaunchControl側でエラーが出たとき、こういう書き方に変えてfdautilでフルディスク権限を与えて実行しますか?と誘導される場合があったが、最終的には不要だった
/usr/local/bin/fdautil exec ../screenshot/capture.sh)

ハマったとき

  • shをターミナルから動かしてスクリーンショットが撮れるか確認する
    • 動作するが、デスクトップ背景が撮れているときは→権限不足
  • ターミナルでは動作するが、launchdでは動作しないとき→権限不足または設定ミス→ログを確認する

確認事項

  • キャプチャウィンドウを指定する場合はChromeでなくてSafariにする
  • #!/bin/bash がない(bashのとき)
  • ファイル権限がない
    • chmod 755 /path/to/file.sh
  • 保存するディレクトリに権限がない
    • chmod 755 /path/to/dir/
  • Mac側の権限が足りない
    • プライバシーとセキュリティ→画面収録で bashに権限を付与。+ボタンからcmd+shift+Gで/bin/bashを選択
    • (場合によっては以前から権限をつけている場合もあるので、ファイルとフォルダ、フルディスクアクセス等も確認)
  • Desktop/ 配下にスクリプトがある
    • デフォルトのディレクトリは避けて、root配下にする
  • launchdのxmlで対象スクリプトのパスが設定できていない

まとめ

  • Macでスクリーンショットを定期的に取る方法についてのメモ
    • スクリーンショット以外の動作も可能です
  • ほとんどChatGPTに聞きながらやりました
  • Macの権限周りは慣れないとハマる(ハマった)、という感想です

Appendix

時間指定での動作

com.yourusername.screencapture.plistを変更

この部分を

com.yourusername.screencapture.plist
    <key>StartInterval</key>
    <integer>3600</integer>

このように変えると、0分、30分毎時に変えたりできます。

    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Minute</key>
            <integer>0</integer>
        </dict>
        <dict>
            <key>Minute</key>
            <integer>30</integer>
        </dict>
    </array>

python スクリプトの実行

このようにpythonの実行ファイルのパスを書けばよいそうです。/usr/bin/python3の部分は環境によります。

        <string>/usr/bin/python3</string>
        <string>/path/to/file.py</string>

screencaptureで画面を選択してキャプチャ

(Macの場合)

どの画面がどれかは、システム設定のディスプレイから確認できます。左から1,2,3で、指定しないと1になります。

2つめを指定したい場合は、

screencapture -x -D2 "$output_file"

のように -D2 オプションを追加すればよい。

Discussion