5
2

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.

RPA ChallengeをあえてAutomation Anywhereで解いてみる

Last updated at Posted at 2019-12-14

RPA Challengeとは

RPA ChallengeはUiPath社によって運営されている、自動化が難しいWebサイトを創意工夫して速く正確に自動化する課題を提供するサイトです。通常はUiPathのロボットを使って課題を解くのでしょうか、ここは敢えてAutomation Anywhere社が提供しているRPAで解いてみるということをしたいと思います。

使用環境

  • Automation Anywhere Enterprise v11.3.2 / v11.3.3

image.png

課題の概要

「Input Forms」という課題には日本語も用意されています。これは、ダウンロードしたExcelファイルの中にあるダミーの個人情報をRPAでWebフォームに入力していく課題です。ただし、Webページのフォーマットは登録ボタンを押すごとに毎回変わり、入力フィールドの位置、順番は一定ではありません。加えて、フィールドにつけられているIDも "x05y7" などランダムな文字列で毎回異なるため、DOMやXPathでフィールドを特定することも困難です。

たとえば、フォームのHTMLは以下のような形です。いまはメールアドレス、住所、...の順番で並んでいますが、この並び方は毎回異なり、レイアウトも異なることがあります。

<form _ngcontent-c1="" novalidate="" ng-reflect-form="[object Object]" class="ng-untouched ng-pristine ng-invalid">

<div _ngcontent-c1="" class="row"><!--bindings={
  "ng-reflect-ng-for-of": "[object Object],[object Object"
}-->

<div _ngcontent-c1="" class="col s6 m6 l6">
<rpa1-field _ngcontent-c1="" _nghost-c2="" ng-reflect-id="8iWmb" ng-reflect-dictionary-value="メールアドレス" ng-reflect-label="labelEmail" ng-reflect-parent-form-group="[object Object]">
  <div _ngcontent-c2="" ng-reflect-form="[object Object]" class="ng-untouched ng-pristine ng-invalid">
    <label _ngcontent-c2="">メールアドレス</label>
    <input _ngcontent-c2="" ng-reflect-name="labelEmail" id="8iWmb" name="8iWmb" class="ng-untouched ng-pristine ng-invalid">
  </div>
</rpa1-field>
</div>

<div _ngcontent-c1="" class="col s6 m6 l6">
<rpa1-field _ngcontent-c1="" _nghost-c2="" ng-reflect-id="kFce2" ng-reflect-dictionary-value="住所" ng-reflect-label="labelAddress" ng-reflect-parent-form-group="[object Object]">
  <div _ngcontent-c2="" ng-reflect-form="[object Object]" class="ng-untouched ng-pristine ng-invalid">
    <label _ngcontent-c2="">住所</label>
    <input _ngcontent-c2="" ng-reflect-name="labelAddress" id="kFce2" name="kFce2" class="ng-untouched ng-pristine ng-invalid">
  </div>
</rpa1-field>
</div>

...

<input _ngcontent-c1="" class="btn uiColorButton" type="submit" value="登録">
</form>

例1:
image.png
例2:
image.png
例3:
image.png

Automation Anywhere による結果

今回は、試行錯誤の結果「約7秒で正解率100%でクリア」までもっていくことができました。さらなるチューニングをAutomation Anywhere上でできるかどうか、試してみてください。
image.png

(以下ネタバレ含む) 課題の解き方

以下の章では、この課題の解き方を考え方とともに順を追ってみていきます。ネタバレを含みますので、自分で解きたい人は見ないでください。

課題への着眼点

RPA Challengeの課題を解くポイントですが、登録フォームが毎回変わる中で、「普遍的に変わらないものを見極め、それをうまく利用する」ことです。今回の場合はlabelに表示される7種類のテキストは同じで、かつlabelの次のコントロールとして必ずinputが来るように見えるので、そのことを利用して、まず特定のlabelを探して、その次に位置するinputに、対応する値を代入するようにすれば解決しそうです。

特定フィールドへの入力手段を確立する

では、実際にやってみましょう。Internet ExplorerでRPA Challengeのページを表示したら、Object Cloningコマンドを使って「会社名」のラベルを捕捉してみましょう。コマンドをドラッグ&ドロップすると、以下のようなダイアログボックスが表示されます。
image.png

「リフレッシュ」ボタンを押してドロップダウンから「Rpa Challenge - Internet Explorer」というウィンドウを選択して「キャプチャ」ボタンを押します。

以下のように、LABELのHTML Tagが取得できていれば成功です。
image.png

「検索条件を選択」の右側にある「検索条件を展開 (image.png)」ボタンをクリックすると、その他に取得できたプロパティの一覧も表示されます。「HTML Inner Text」に「会社名」というラベル名が取得できていると思います。

image.png

そして、inputフィールドが常にlabelの次に来ることを思い出しましょう。そして、HTMLフォームでは、「TABキーを押すことで次のコントロールに移れる」という一般的な動作規則を使って、捕捉したlabelコントロールの隣のinputフィールドにフォーカスを移動することにします。

先ほどの「会社名」labelを補足したObject Cloningコマンドのダイアログボックスで、「実行するアクションの選択」から「Click」を選んでおきましょう。
image.png
labelをクリックしておくことで、このコントロールに最初にフォーカスを合わせておくことができます。TABキーを押すと、次のinputフィールドにフォーカスを移せます。フォーカスを移した後は、inputフィールドに、ひとまずラベルと同じ「会社名」と入力しておくことにしましょう。TABキーと文字列の入力はInsert Keystrokesコマンドを使います。「キーボード操作」のフィールドには、特殊キーとしてダイアログボックスの下側の仮想キーボードからTABを押して入力します。(テキストで"[TAB]"と直接入力してもOK)
image.png

そうすると、以下のようなアクションリストが出来上がります。
image.png

これで、「会社名」フィールドがいろいろな位置に出てきたときに正しく文字が入力できるか試してみてください。正しいフィールドに文字が入らない時 (たとえばInternet Explorerのアドレス部分に入ってしまうなど)は、Object Cloningコマンドでlabelコントロールを正しく捕捉できていないことになります。

先ほどのObject Cloningダイアログボックスに戻り、オブジェクトの検索条件をON/OFFしていろいろ試行錯誤してみましょう。双眼鏡マーク (image.png)がついているプロパティが検索対象になっています。試行錯誤をした結果、今回は、HTML Inner Textのみを検索条件に指定するとうまくいくことがわかりました。つまり、「会社名」という文字列が埋め込まれているコントロールを検索してくる、という条件を指定するとうまくいく、ということになります。

ためしに「会社名」と「苗字」の2つのフィールドに連続して文字列を入れるアクションリストを組んで試してみましょう。
image.png

結果は以下のようになるはずです。
image.png
これで、あとはフィールドの数だけアクションをコピーしていけば、全フィールドへの入力ができるようになります。
image.png

アクションリストと結果はこんなかんじです。
image.png
image.png

Excel からの入力部分を作る

ここまで出来たら、次にいままでダミーでinputフィールドに入れていた文字列をExcelから読み込んだ文字列で置き換えます。RPA Challengeのページからダウンロードできるchallenge_ja.xlsxの内容は以下の通りです。
image.png

注: なぜかGet All Cellsコマンドでエラーが出てしまったため、このシートのデータの書式をすべて落としてchallenge_ja1.xlsxとして保存して、これを使用しました。

RPAでExcelを操作する際のヒント (Automation Anywhere編)」のLoop > Each Row in an Excel datasetのサンプルに掲載されているサンプルに倣い、Excelファイルからの読み込み部分を作成します。以下はExcelの表から読み込むサンプルです。
image.png
また、ループの最後に最後に「登録」ボタンをクリックする動作を加えます。あと、Get All CellsコマンドでExcelデータを読み込んだ直後に「開始」ボタンを押す操作も加えます。

注: Object Cloningでうまく目的のコントロールが選択できないときは、プロパティの値を手入力してみましょう。Firefoxのウェブ開発モードで使えるインスペクターでタグを調べるとよいでしょう。
image.png

開始ボタン
<button _ngcontent-c1="" class="waves-effect col s12 m12 l12 btn-large uiColorButton">開始</button>

検索条件:
image.png

登録ボタン
<input _ngcontent-c1="" class="btn uiColorButton" type="submit" value="登録">

検索条件:
image.png

追加後のアクションリストがこちらです。
image.png

このアクションリストでボットをv11.3.2 実行した結果、以下のような結果となりました。(正解率約70%、所要時間約30秒)
image.png

エラー率の改善とスピードチューニング

ここまでで課題が大きく2点あります。ひとつは正解率が低いことです。これは、実行中の様子を注意深く見ていると、正しいフィールドを選べているかについては100%の正解率でしたが、入力される文字列の前 or 後ろが切れて入力されることがあるようでした。これはキーストロークのエミュレーションによるタイミングの問題と思われます。2つ目は時間がかかりすぎることです。期待値の約10倍の時間がかかっています。これも同じくキーストロークのエミュレーションが遅いことによるものと思われます。つまり、両方ともアクションリストでいうと9, 12, 15, 18, 21, 24, 27行目をチューニングする必要があります。

ちなみに、v11.3.3で実行してみると、正解率98% (1つ間違え)、所要時間約38秒となりました。バージョンによって結構違いますね。Keystokeでのタイミングの取られ方が変わったようで、キーストロークによる入力漏れが圧倒的に減りましたが、時間がかかるようになりました。
image.png

そこで、キーストロークやラベルにタブを打って次のコントロールを指定するのをやめて抜本的にやり方を変えることにしました。HTMLをよく見てみると、inputフィールドの順番が変わっても、属性でフィールドの種類がわかるものがあることがわかりました。

ng-reflect-name="labelAddress" ⇒ 苗字フィールド
ng-reflect-name="labelAddress" ⇒ 名前フィールド
ng-reflect-name="labelAddress" ⇒ 会社名フィールド
ng-reflect-name="labelAddress" ⇒ 部署フィールド
ng-reflect-name="labelAddress" ⇒ 住所フィールド
ng-reflect-name="labelAddress" ⇒ メールアドレスふぃーづろ
ng-reflect-name="labelAddress" ⇒ 電話番号フィールド

そこで、Manage Web Controlコマンドを使って各inputフィールドをキャプチャーして、識別に使う属性を手で変更することにしました。たとえば、最初の「苗字」フィールドをキャプチャしてみましょう。
image.png
キャプチャーした直後のManage Web Controlコマンドのダイアログボックスは以下の通りです。そこに赤字で書いた変更を加えます。
image.png
変更後のダイアログボックスは以下の通りです。
image.png

これをあとの6つのフィールドに対しても行います。

最終的なアクションリスト

最終的には、さきほどのものよりも行数が少なくシンプルなものになりました。
image.png

これをv11.3.3で実行してみると、先ほどよりもだんぜんはやくなりました。正解率100%、約7秒で完了です。だいぶチューニングされました。
image.png

これ以上チューニングの余地があるのかどうかわかりませんが、皆さんもぜひ試してみてください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?