無料RPAツールのAutoITを使用してChromeを操作してExcelデータを読み込みGoogleフォームへの入力を自動化する方法を紹介します。業務上で様々な活用が想定されますが、今回は出張旅費データの精算時作業を想定した例としています。
この記事のターゲット
この記事は以下のような方をターゲットとしています。
- ExcelVBA/マクロは使ったことがあるが、さらに踏み込んだ自動化をしたい
- RPA的なデスクトップ操作を含めた自動化を試したい
- AutoITを使っていてExcelとChromeの連携を行いたい
- UWSCを使っているがChrome連携ができず困っている
完成品はこちら
ソースコード
#include <wd_core.au3> ;WebDriverを使うためモジュール
#include <Excel.au3> ;Excelを使うためのモジュール
; // 定数設定 //
const $maxRow=99 ;Excelから読み込む最大行数
const $maxCol=9 ;Excelから読み込む最大列数
const $fileName="C:\Users\user\Desktop\inputdata.xlsx" ;読み込むファイル名
const $targetURL="https://forms.gle/r42yqUVwANn7NP246" ;入力フォームのURL
; // クローム設定 //
_WD_Option('Driver', 'C:\wd\chromedriver.exe') ;webdriverを指定
_WD_Option('DriverParams', ' --verbose --log-path=' & @ScriptDir & '\wdlog.log');ログ出力を指定
_WD_Option('Port', 9515) ;ポート指定
$sdesire = '{"capabilities": {"alwaysMatch":{"goog:chromeOptions":{"w3c": true, "args":["--disable-gpu-early-init,"]}}}}'
; // 入力先のGoogleフォームのXPATH //
Dim $xp[$maxCol];XPATHの格納先
$xp[0]='//*[@id="mG61Hd"]/div/div/div[2]/div[1]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム1
$xp[1]='//*[@id="mG61Hd"]/div/div/div[2]/div[2]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム2
$xp[2]='//*[@id="mG61Hd"]/div/div/div[2]/div[3]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム3
$xp[3]='//*[@id="mG61Hd"]/div/div/div[2]/div[4]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム4
$xp[4]='//*[@id="mG61Hd"]/div/div/div[2]/div[5]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム5
$xp[5]='//*[@id="mG61Hd"]/div/div/div[2]/div[6]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム6
$xpSend='//*[@id="mG61Hd"]/div/div/div[3]/div[1]/div/div' ;送信ボタン
$xpNext='/html/body/div[1]/div[2]/div[1]/div/div[4]/a' ;もう一度回答するボタン
; // Excelからデータを読み込む //
Dim $val[$maxRow][$maxCol] ;データの格納先
; Excelの起動
$oExcel = _Excel_Open()
; ファイルを指定して開く
$oWorkbook = _Excel_BookOpen($oExcel,$fileName)
; エラー処理
If @error Then
Msgbox(4096,"error", "excelファイルが開けませんでした。")
Exit
EndIf
; データの読み込み
For $i=0 To $maxRow-1 Step 1
for $j=0 To $maxCol-1 Step 1
$val[$i][$J]=$oWorkbook.Sheets(1).Cells($i+2,$j+1).Value ; データを二次元配列に格納(2行目からデータを読み込む)
_FileWriteLog(@ScriptDir & "\readExcelToForm.log",$i+2&"-"&$j+1&":"&$val[$i][$j]) ;ログ出力
Next
If $val[$i][0]="" Then ExitLoop ;データがなければループを抜ける
Next
; ブックを閉じてExcelを終了
_Excel_BookClose($oWorkbook)
_Excel_Close($oExcel)
;// Googleフォームにデータを打ち込む //
; 黒い画面(Chrome WebDriver)が立ち上がる
Local $pid = _WD_Startup()
If @error Then
Msgbox(4096,"error", "webdriverの起動に失敗しました")
Exit
EndIf
;セッションを追加 ChromeDriver経由でChrome新ウィンドウが立ち上がる
$sess = _WD_CreateSession($sdesire)
If @error Then
MsgBox(4096, "error", "ブラウザ立ち上がりませんでした")
Exit
EndIf
;このサイトを表示する
Sleep(1000) ;表示されるまでの時間待ち受ける(ミリ秒指定)
_WD_Navigate($sess, $targetURL) ; URLを開く
; エラー処理
If @error Then
MsgBox(4096, "error", "指定したUrlを開けませんでした。 extended=" & @extended )
EndIf
Sleep(3000)
; Excelデータを1行づつフォームに入力して送信
for $i=0 To $maxRow-1 Step 1 ; 行数分繰り返し
for $j=0 To $maxCol-1 Step 1 ; 列数分繰り返し
actionElement($sess,$xp[$j],'value',$val[$i][$j]) ; input要素に対して値の入力を行う
Next
actionElement($sess,$xpSend,'Click') ;送信ボタンをクック
; 次のデータがあれば、もう一度入力するボタンをクリック
If $val[$i+1][0]="" Then
ExitLoop ;データがなければループを抜ける
Else
actionElement($sess,$xpNext,'Click') ;次もう一度入力するボタンをクリック
EndIf
Next
; エラー処理
If @error Then
MsgBox(4096, "error", "フォーム入力時にエラーが発生しました")
EndIf
; chromeを閉じる
_WD_Window($sess, "close")
_WD_DeleteSession($sess)
_WD_Shutdown() ; webdriverを終了
; // HTML要素に対してアクション(クリック、文字入力等)する関数 //
Func actionElement($s,$xp,$action,$val="")
; 要素を見つける
$obj=_WD_FindElement($s, $_WD_LOCATOR_ByXPath, $xp)
; 要素に対してアクションする
_WD_ElementAction($s, $obj, $action,$val)
EndFunc
入力データ
出張旅費精算をイメージしたデータとしています。
動作GIF
解説
前提条件
以下のライブラリ、ドライバーが必要になりますので、URLからダウンロードしてくだ
WebDriver UDFライブラリ
JSON UDFライブラリ
_Json.zipファイルを解凍し、AutoITインストールフォルダのincludeに格納してください。
WinHTTP ライブラリ
WinHttp.zipファイルを解凍し、AutoITインストールフォルダのincludeに格納してください。
WebDriver
アドレスバーに『chrome://settings/help』と打ち込みChromeのバージョンを確認し、適したバージョンをダウンロードしてください。
https://sites.google.com/a/chromium.org/chromedriver/downloads
インストール先は、【C:\wd】としています。変更する場合は、コード内の以下の指定を変更する必要があります。
_WD_Option('Driver', 'C:\wd\chromedriver.exe') ;webdriverを指定
コード解説
前処理
『wd_core.au3』と『Excel.au3』の2つのファイルをインクルードしています。これらは、Chromeを操作するためのモジュールと、Excelを操作するためのモジュールです。
『$maxRow』と『$maxCol』でExcelから読み込む最大行数と列数を定義しています。必要に応じて変更してください。『$fileName』で読み込むファイル名のフルパスを指定しています。『$targetURL』は入力フォームのURLです。
#include <wd_core.au3> ;WebDriverを使うためモジュール
#include <Excel.au3> ;Excelを使うためのモジュール
; // 定数設定 //
const $maxRow=99 ;Excelから読み込む最大行数
const $maxCol=9 ;Excelから読み込む最大列数
const $fileName="C:\Users\user\Desktop\inputdata.xlsx" ;読み込むファイル名
const $targetURL="https://forms.gle/r42yqUVwANn7NP246" ;入力フォームのURL
_WD_Optionにてドライバーやログ出力先の指定をしています。
; // クローム設定 //
_WD_Option('Driver', 'C:\wd\chromedriver.exe') ;webdriverを指定
_WD_Option('DriverParams', ' --verbose --log-path=' & @ScriptDir & '\wdlog.log');ログ出力を指定
_WD_Option('Port', 9515) ;ポート指定
$sdesire = '{"capabilities": {"alwaysMatch":{"goog:chromeOptions":{"w3c": true, "args":["--disable-gpu-early-init,"]}}}}'
AutoITではWeb操作でHTML要素を指定するためのXPathを使用します。
複雑な値ですが、簡単に取得できるので安心してください。
XPathはXML文章中の要素、属性値などを指定するための言語です。XPathではXML文章をツリーとして捉えることで、要素や属性の位置を指定することができます。HTMLもXMLの一種とみなすことができるため、XPathを使ってHTML文章中の要素を指定することができます。
クローラ作成に必須!XPATHの記法まとめ https://qiita.com/rllllho/items/cb1187cec0fb17fc650a
; // 入力先のGoogleフォームのXPATH //
Dim $xp[$maxCol];XPATHの格納先
$xp[0]='//*[@id="mG61Hd"]/div/div/div[2]/div[1]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム1
$xp[1]='//*[@id="mG61Hd"]/div/div/div[2]/div[2]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム2
$xp[2]='//*[@id="mG61Hd"]/div/div/div[2]/div[3]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム3
$xp[3]='//*[@id="mG61Hd"]/div/div/div[2]/div[4]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム4
$xp[4]='//*[@id="mG61Hd"]/div/div/div[2]/div[5]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム5
$xp[5]='//*[@id="mG61Hd"]/div/div/div[2]/div[6]/div/div[2]/div/div[1]/div/div[1]/input' ;入力フォーム6
$xpSend='//*[@id="mG61Hd"]/div/div/div[3]/div[1]/div/div' ;送信ボタン
$xpNext='/html/body/div[1]/div[2]/div[1]/div/div[4]/a' ;もう一度回答するボタン
(補足)XPathの取得方法
XPathを取得したい要素をクリックした状態で右クリックし、検証を選択します。
右上のHTML要素を選択すると、青色く色が変わるので入力した要素に合わせます。
右クリック → Copy → Copy XPath と選択します。クリップボードに値がコピーされるので、コードに張り付けます。
Excelからのデータ読み込み
AutoITも一般的な言語と同様に二次元配列を扱えるため、Cells関数を使いセル要素にアクセスして、二次元配列に格納しています。Excelの操作はExcelVBAに近いため、とっつきやすいかと思います。Excelの一列目にデータがない場合はデータ終了とみなして読み込みを完了させるようにしています。
; // Excelからデータを読み込む //
Dim $val[$maxRow][$maxCol] ;データの格納先
; Excelの起動
$oExcel = _Excel_Open()
; ファイルを指定して開く
$oWorkbook = _Excel_BookOpen($oExcel,$fileName)
; エラー処理
If @error Then
Msgbox(4096,"error", "excelファイルが開けませんでした。")
Exit
EndIf
; データの読み込み
For $i=0 To $maxRow-1 Step 1
for $j=0 To $maxCol-1 Step 1
$val[$i][$J]=$oWorkbook.Sheets(1).Cells($i+2,$j+1).Value ; データを二次元配列に格納(2行目からデータを読み込む)
_FileWriteLog(@ScriptDir & "\readExcelToForm.log",$i+2&"-"&$j+1&":"&$val[$i][$j]) ;ログ出力
Next
If $val[$i][0]="" Then ExitLoop ;データがなければループを抜ける
Next
; ブックを閉じてExcelを終了
_Excel_BookClose($oWorkbook)
_Excel_Close($oExcel)
Googleフォームへの入力
actionElement関数は自作の関数で、『要素の取得』と『要素に対するアクション』を行っています。第二引数にXPath、第三引数にアクション、第四引数に入力値を入れます。アクションがvalue以外の時は第四引数は省略します。
; // HTML要素に対してアクション(クリック、文字入力等)する関数 //
Func actionElement($s,$xp,$action,$val="")
; 要素を見つける
$obj=_WD_FindElement($s, $_WD_LOCATOR_ByXPath, $xp)
; 要素に対してアクションする
_WD_ElementAction($s, $obj, $action,$val)
EndFunc
データを1行分フォームに入力→送信→もう一度入力するボタンをクリック を1セットとして、行数分繰り返しています。
; Excelデータを1行づつフォームに入力して送信
for $i=0 To $maxRow-1 Step 1 ; 行数分繰り返し
for $j=0 To $maxCol-1 Step 1 ; 列数分繰り返し
actionElement($sess,$xp[$j],'value',$val[$i][$j]) ; input要素に対して値の入力を行う
Next
actionElement($sess,$xpSend,'Click') ;送信ボタンをクック
; 次のデータがあれば、もう一度入力するボタンをクリック
If $val[$i+1][0]="" Then
ExitLoop ;データがなければループを抜ける
Else
actionElement($sess,$xpNext,'Click') ;次もう一度入力するボタンをクリック
EndIf
Next
; エラー処理
If @error Then
MsgBox(4096, "error", "フォーム入力時にエラーが発生しました")
EndIf
; chromeを閉じる
_WD_Window($sess, "close")
_WD_DeleteSession($sess)
_WD_Shutdown() ; webdriverを終了
まとめ
AutoITを使いChromeを操作しExcelデータのWebサイト入力を自動化する方法を紹介しました。Excel→Webサイトへの明細入力は、業務でも比較的多くみられるパターンかと思います。
これを効率化できれば効果は非常に高います。AutoITは非常にポテンシャルの高いツールでありますので、今後も有用な実装を検証し公開していきます。
AutoITに関する書籍はあまりなく学習が大変ですが、英語に抵抗のないかたは以下の書籍良いかもしれません。
コメント