自動操作+スクリーンショット保存プログラム

作ったもの

スクリーンショット保存及びキーボード入力操作等を自動化するプログラム。
具体的には、以下の動作を自動化するプログラム。

  • スクリーンショットを撮影する
  • 前回撮影したスクリーンショットと異なる画像だったら、スクリーンショットを保存し、次に進む操作を行う
    • 同じ画像だったら、次に進む操作を行う

作成した背景

とある電子書籍プラットフォームで、書籍が非常に安く販売されていた。
(他のプラットフォームに比べ、30%くらい割引率が高かった。)
基本的には電子書籍プラットフォームは特定の1つに統一したいところだが、さすがに30%安いのは無視できない差だったため、普段とは別のプラットフォームで購入することとした。
しかしながら、いつもとは違う電子書籍プラットフォーム用のアプリを使ったところ、あまりにも使いづらかった(動作がもっさりしている)ため、どうにかして普段の電子書籍プラットフォーム用アプリで開けるようにしたくなった。
そこで、あるアプリ上で書籍を開き、全ページをスクリーンショットで保存し、pdfファイルに固めることでいつものアプリで開けるようなファイルを作成することとした。
(自分の調べた範囲では、個人利用のためスクリーンショットを撮影することに法的な問題はないらしい。)
本プログラムは作ったもので説明した通り、スクリーンショット撮影を自動化するためのプログラムである。

使い方

①スクリーンショット撮影を行いたいアプリを起動する

②スクリーンショット撮影をしたい領域をプログラム中(14行目)で指定する

③以下のディレクトリ構成となるよう「auto_screenshot.py」と「ss」フォルダを作成・配置し、「auto_screenshot.py」を実行する。

  • ルートディレクトリ
    • auto_screenshot.py
    • ss

④プログラムの処理は「Ctrl+C」などで強制的に終了させる。

ソースコード(auto_screenshot.py)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyautogui#スクリーンショットを撮ったりキーボード操作を行うため
import time#sleepするため
import hashlib#スクリーンショット画像の変化を検出するため
def main():#メイン関数
    #プログラム実行開始後、自動撮影したいウィンドウをアクティブにするまでの待機時間
    time.sleep(3)
    #インスタンスの作成:初期値(撮影領域など)の設定+表紙の撮影・保存
    #スクリーンショットを撮影したい領域に合わせて適切に設定すること
    ss=SS(3, 271, 1072, 1381)
    #「次へ進む」操作をするインターバルタイム
    #次へ進む操作~画面の更新までの時間より十分大きい値を設定するとよい
    interval_time=0.2
    #次へ進む
    ss.proceed_action()
    while True:
        ss.get_SS()#スクリーンショットを撮影
        if ss.check_hash():#前の画像と異なる画像だったときの処理
            ss.save_SS()#スクリーンショットを保存し、時刻を記録し、次に進む
            time.sleep(interval_time)
        else:#前の画像と同じ画像だったときの処理
            #最後に画像を保存してから一定時間以上経過していたら(一定時間以上同じ画像が表示されていたら)
            #次に進む操作に失敗していると考えられるため、次に進む操作をやり直す
            ss.retry_proceed(3.0)
            time.sleep(interval_time)
class SS:
    #コンストラクタ:インスタンスを作成した時に、初期値を設定する
    def __init__(self,x,y,wx,wy,counter=1):
        self.x=x#スクリーンショットを撮り始める位置X[px]
        self.y=y#スクリーンショットを撮り始める位置Y[px]
        self.wx=wx#スクリーンショットを撮る幅[px]
        self.wy=wy#スクリーンショットを撮る高さ[px]
        self.get_SS()#最初の画像(表紙)を取得し、現在のハッシュ値を計算
        self.prev_hash=self.hash#最初の画像のハッシュ値を過去のハッシュ値に代入
        self.last_updated_time=time.time()#最初の画像を取得した時刻を保持
        self.counter=counter#画像の通し番号の初期値を設定
        self.save_SS()#最初の画像を保存
    #スクリーンショットを撮り、ハッシュ値を更新するメソッド
    def get_SS(self):
        #指定範囲でスクリーンショットを撮影
        self.screen_shot = pyautogui.screenshot(region=(self.x,self.y,self.wx,self.wy)) 
        #撮影したスクリーンショットのハッシュ値を計算
        self.hash = hashlib.md5(self.screen_shot.tobytes()).hexdigest() 
    #最後に撮影したスクリーンショットの保存→カウンターを更新→次へ進むキー操作をするメソッド
    def save_SS(self):
        self.screen_shot.save("ss/{:04}.png".format(self.counter))#0埋め4桁の連番画像として保存する
        print("ss/{:04}.png".format(self.counter))
        self.counter+=1
        self.prev_hash=self.hash
        self.last_updated_time=time.time()#画像を保存した時刻を保持
        self.proceed_action()
    #最後に画像のハッシュ値を更新してから一定時間以上経過していたら、操作をやり直す
    def retry_proceed(self,retry_time):
        #一定時間以上スクリーンショット画像が更新≒保存されないとき、
        #次へ進むキー操作入力に失敗していると判定し、キー操作をやり直す
        if time.time()-self.last_updated_time>retry_time:
            self.proceed_action()
    #前回のスクリーンショットと今回のスクリーンショットが異なる画像かどうかを判定するメソッド
    #前回の画像と今回の画像のハッシュ値が異なる時Trueを返す
    def check_hash(self):
        res=True
        if self.prev_hash==self.hash:#ハッシュ値が一致したら同じ画像
            res=False
        else:
            res=True
        return res
    #次に進むためのキー操作を指定するメソッド
    #システムが変わったり操作入力内容が変わったら、ここを書き換える
    def proceed_action(self):
        pyautogui.press("right")
#メインの処理
if __name__ == "__main__":
    main()

コメント