5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PyAutoGuiで確認ダイアログが出てくるようなバッチ処理を止めずに自動化しよう

Last updated at Posted at 2019-01-19

忙しいけど、どうしても単調なことをしないといけない。
例えば、とあるツールに大量のデータを読み込ませて処理をさせないといけないけど、そのツールが正しくGUIツールで、いちいち確認ダイアログとか押さないと次に進まない!!!って言うようなやつ。
平たく言えば、そういうのはそもそも設計的に想定していなかった用途だけど、それしか使うものがないから仕方なく使うけど、大量データを食わせて動作させると発狂しそうな作業になったりする。

僕もたまたまそういう作業にぶち当たり、これはなんとかならんか・・・と思いたち、色々調べていると、以下の記事を拝見しました。

PyAutoGuiで繰り返し作業をPythonにやらせよう

なるほど、PyAutoGuiってので大変便利なことが出来るわけか。よし、やってみよう。

と言うことで、スクリプトを作成してみました。
上記記事をベースにしながら、

How to emulate button click with Python and winapi?
これも参考にして、ボタンを取得する動作を実装した。

また、僕はVisual Studioコードでデバッグしながら実際の処理も動かすモノグサなんだけれど、clickメソッドが実行されてるのに対象ウィンドウのボタンが押されないので何かと思って調べてみると、

Application not responding to Windows API events?にある通り、管理者権限でないと動作しないみたいだった。
VS Codeを管理者権限で起動すると、うまく動作した。

さて、スクリプトは以下の通りとなった。
ちなみに当方の動作環境は以下の通り。

  • Python 3.7.0
  • Windows7 SP1 64bit

# -*- coding: utf-8 -*-

import time
import win32gui
import win32api
import pyautogui

count = 0
child_list = []
#指定されたボタン名のハンドルをリストに追加
def add_to_list(hwnd, param):
    if win32gui.GetWindowText(hwnd) == "ボタン名":
        child_list.append(hwnd)

if __name__ == "__main__":

    #ずっと動かすので無限ループ
    while True:
        #ループするたびに空にしておく。
        #5秒ごとに実行する。
        child_list = []
        time.sleep(5)

        #対象ウィンドウを取得。第二引数にウィンドウタイトルを指定。
        hwnd = win32gui.FindWindow(None, "対象ウィンドウタイトル")

        if hwnd <= 0:
            continue

        #ハンドルがある場合、子要素をすべて列挙してリストに突っ込む。
        win32gui.EnumChildWindows(hwnd,add_to_list,None)

        if len(child_list) == 0:
            continue

        if child_list[0] == 0:
            continue

        #対象のハンドルが取得出来たと言うことは、指定された名前のボタンがあったと言うこと。
        #そいつの座標を取得する。
        rect = win32gui.GetWindowRect(child_list[0])
        x = (rect[0]+rect[2])/2
        y = (rect[1]+rect[3])/2
        pyautogui.moveTo(x,y,duration=1)
        pyautogui.click(x,y,button='left')
        count=count+1
        print(str(count)+"回終了")

これを実行している間は、定期的にカーソルが動くので、放置プレイがおすすめ。


pyautogui.moveTo(x,y,duration=1)

の部分をコメントアウトするとカーソルが移動する動作はなくなるが、瞬時にカーソルが移動するようになるので、いずれにせよあまり向かない。
また、クリックする性質から、対象ウィンドウは見えてなきゃいけない。
諸々の制約はあるけど、それを乗り越えれば、人間がトイレに行っている間もマシンは文句も言わず黙々と仕事をしてくれているはずだ。

5
6
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
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?