AutoITでChromeを操作しExcelデータをGoogleフォームへ自動入力する方法

AutoIT

無料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ライブラリ

GitHub - Danp2/au3WebDriver: Web Driver UDF for AutoIt
Web Driver UDF for AutoIt. Contribute to Danp2/au3WebDriver development by creating an account on GitHub.

 

JSON UDFライブラリ

_Json.zipファイルを解凍し、AutoITインストールフォルダのincludeに格納してください。

A Non-Strict JSON UDF (JSMN)
Introduction JSON (Javascript Object Notation) is a popular data-interchange format and supported by a lot of script languages. On AutoIt, there is already a >J...

 

WinHTTP ライブラリ

WinHttp.zipファイルを解凍し、AutoITインストールフォルダのincludeに格納してください。

Releases · dragana-r/autoit-winhttp
Automatically exported from code.google.com/p/autoit-winhttp - dragana-r/autoit-winhttp

 

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に関する書籍はあまりなく学習が大変ですが、英語に抵抗のないかたは以下の書籍良いかもしれません。

コメント

タイトルとURLをコピーしました