操作の自動化

作成日 : 2018-11-04
最終更新日 :

コンピュータの自動化

このページではコンピュータの自動化について記す。 なお、WEB アプリケーションのスクレーピングなど、関連する話題は下記にある。

コンピュータそのものは自動化のためにあるものだが、対話式に画面で操作しなければならないアプリケーションは、 長らく自動化の対象から外れていた。しかし、コンピュータ技術が進歩し、特に画像を認識する機能が充実してきたことから、 画面を対象に今まで人間が能動的に指示してきた作業もコンピュータができるようになってきた。 最近(私の中では 2018 年ごろ)、ロボティック・プロセス・オートメーションということばを耳にするようになった。 英語では RPA(Robotic Process Automation)という。RPA というと、企業が専用の有償プログラムを使って取り組むイメージが私にはある。 このページでは一個人が RPA もどきを無償のプログラムで使ってできることを考える。

自動化の対象

自動化する対象はグラフィカル・ユーザー・インターフェース( GUI )のあるプログラムである。GUI には大きく分けて WEB ブラウザを使うものと使わないものがある。 そこで、自動化を行うツールも、ブラウザに特化せず GUI のあるプログラムであれば使えるものと、ブラウザに特化したものとがある。以下、前者を GUI 自動化、 後者をブラウザ自動化と呼ぶ。ブラウザ自動化には Selenium というツール・ライブラリ群が知られている。また、Node.js を使う Puppeteer というライブラリもある。これらについては、追って準備する予定である。 以下は、GUI 自動化について述べる。

GUI 自動化

GUI 自動化を行なうツール群として、Python をプログラム言語として使う PyAutoGUI や PyWinAuto がある。両者の違いは、PyAutoGUI がマウスや画面を主体としているのに対し、 PyWinAuto はウィンドウの構成部品をテキストベースで分解して扱うという特徴がある。以下、PyAutoGUI について述べる。

PyAutoGUI

次の conda コマンドでインストールする(https://anaconda.org/conda-forge/pyautogui)
conda install -c conda-forge pyautogui
私の環境(Windows 11 Home Edition)では上記でインストールできた。

使えそうな関数

Screenshot Functions (pyautogui.readthedocs.io) などを参考にした。

screenshot(region=(left, top, width, height))
指定した範囲のスクリーンショットを Image オブジェクトとして返す

VBA : Excel で Internet Explorer を操作する

以下は Excel の VBA で Internet Explorer の操作をある程度自動化できるコードを載せる。 2023 年となっては Internet Explorer は古いソフトウェアであり、セキュリティの問題もあるので使ってはいけないが、 資料として載せておく。

IEを起動・終了する

Sub IECreateQuit()
    Dim objIE As Object
 
    'IE を起動
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
 
    '5秒停止
    Call WaitSeconds(5)
 
    'IE終了
    objIE.Quit
    Set objIE = Nothing

End Sub

IE を起動させ 高エネルギー加速器研究機構のページに接続させたのち「お問い合わせ」に移動させる

Sub GoToKek()
    Dim objIE As Object
 
    'IE を起動させる
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
 
    ' 高エネルギー加速器研究機構 (kek) に接続
    objIE.navigate "https://www.kek.jp/ja/"
 
    'IEを待機
    Call IEWait(objIE)
 
    '5秒停止
    Call WaitSeconds(5)
 
   '「お問い合わせ」のリンクをクリック
    Call IELinkClick(objIE, "お問い合わせ")
 
    'IEを待機
    Call IEWait(objIE)

End Sub

IE を立ち上げ Google に遷移させ検索窓(テキストボックス)に「VBA」と入力させたのち終了する

Sub GoogleSearch()
    Dim objIE As Object
 
    'IE起動
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
 
    'Googleに接続
    objIE.navigate "https://www.google.com/"
 
    'IEを待機
    Call IEWait(objIE)
 
    '検索窓に「VBA」と入力
    objIE.document.getElementById("gbqfq").Value = "VBA"
 
    '5秒停止
    Call WaitSeconds(5)
 
    'IE終了
    objIE.Quit
 
    Set objIE = Nothing
End Sub

既に立ち上げているIE の接続先を Yahoo に変える。切らない。

既に立ち上げている IE のタイトルバーには "Google" の文字列が入っているものとする。

Sub GoToYahoo()
    Dim objIE As Object 'IEを格納する変数(オブジェクト型)
    Dim shells As Object    '起動中のShellWindow一式を格納する変数
    Dim win As Object   'ShellWindowを格納する変数
    Dim documentTitle As String  'ドキュメントタイトルの一時格納変数

    '起動中の ShellWindow 一式を変数 shells に格納する
    Set shells = CreateObject("Shell.Application")

    'ShellWindowからウィンドウを1つずつ取得して処理する
    For Each win In shells.Windows
        'ドキュメントタイトル取得に失敗したときは無視して処理を継続する
        On Error Resume Next
        documentTitle = win.document.Title
        On Error GoTo 0

        'タイトルバーに "Google" が含まれるかチェックする
        If InStr(documentTitle, "Google") > 0 Then
            '変数objIEに取得したwinを格納する
            Set objIE = win
            'ループを抜ける
            Exit For
        End If
    Next
 
    objIE.Visible = True
 
    'Yahoo! JAPANに接続
    objIE.navigate "https://www.yahoo.co.jp/"

End Sub

以上はサブルーチンであった。他に、サブルーチンから呼び出されている関数を掲げる。

IE を必要なだけ待機させる関数

Public Function IEWait(ByRef objIE As Object)
    Do While objIE.Busy = True Or objIE.readyState <> 4
        DoEvents
    Loop
End Function

指定した秒だけ停止する関数

Function WaitSeconds(ByVal second As Integer)
    Dim futureTime As Date
 
    futureTime = DateAdd("s", second, Now)
 
    While Now < futureTime
        DoEvents
    Wend
End Function

リンクをクリックする関数

Function IELinkClick(ByRef objIE As Object, ByVal anchorText As String)
    Dim objLink As Object
 
    For Each objLink In objIE.document.getElementsByTagName("a")
        If objLink.innerText = anchorText Then
            objIE.navigate objLink.href
            Exit For
        End If
    Next
End Function

ボタンを押す関数

' ここでは "INPUT" と書かれているボタンを押す
Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String)
    Dim objInput As Object
   
    For Each objInput In objIE.Document.getElementsByTagName("input")
        If objInput.Value = buttonValue Then
            objInput.Click
            Exit For
        End If
    Next
End Function

フォームを送信する関数

' ここでは submit 関数を実行する
Public Function IEFormSubmit(ByRef objIE As Object, ByVal action As String)
    Dim objForm As Object
 
    For Each objForm In objIE.Document.getElementsByTagName("form")
        If objForm.action = action Then
            objForm.submit
            Exit For
        End If
    Next
End Function

参考

プルダウンメニューの選択

次のように select 要素がページに用意されているとする。

value が設定されている場合は、value で指定された値を使い以下のように記述するのがわかりやすい:

objIE.Document.getElementById("frukto").value = "frago"

value が設定されていない場合は、以下のようにするしかない:

objIE.Document.getElementById("frukto").SelectedIndex = "1"

インデックスは 0 から始まるので注意すること。

ラジオボタンの選択

次のように select 要素がページに用意されているとする。

得意な言語 日本語 エスペラント ドイツ語

     'ラジオボタンの「エスペラント」を選択
    objIE.Document.getElementsByName("lingvo")(1).Click
 
    'ラジオボタンの「ドイツ語」を選択する
    'objIE.Document.getElementsByName("lingvo")(2).Click

チェックボックス

objIE.Document.getElementsByName("select1[]")(1).Checked = True

id で指定されていて重複がなければ、getElementById メソッドも使用できる。

リンク集

まりんきょ学問所コンピュータの部屋 > 操作の自動化


MARUYAMA Satosi