ラジオボタンオンの行のn列目のtextを取得したい
最下部に、試せるサンプルと、試したことを載せました。
さらにダイタンな方向も追記しました。
Ver.7.2.1のブラウザ操作のシナリオです。
Chrome9xに適合するchromedriver.exeで順調に回ってます。
ラジオボタンオンの行のn列目のtextを取得するニーズ出てきました。
図解です。
あいにく実物やキャプチャやソースの掲載は叶いません。
目的の値①と②をそれぞれ変数①と②に格納したいです。
お知恵を拝借させてください。
「画像マッチング」でしか対応できないものでしょうか?
既存ライブラリの組み合わせでクリアできたりするものでしょうか。
このへんが今のわたしに難攻不落感を抱かせます、、
- ラジオボタンオンのテーブル特定
ラジオボタンを順に「チェック状態取得」してtrueの要素のidを特定
このライブラリの動作確認はVer.7.3.0、、
ブラウザ操作(指定した要素の属性の値を取得)
https://winactor.biz/library/2021/12/20_4943.html
確か最近のスレッドでVer.7.3系以降でないと実行できなかった、、
上位要素tdのHTMLを取得してidとかforの値を抜き出す?
ブラウザ操作ライブラリから若干はみ出る?
trueのidさえ特定できれば、XPathで階層の昇降と列移動は可能か
- ラジオボタンオンの行番号特定
順に「チェック状態取得」してtrueだったらカウンタの値を行番号とする
trueのidさえ特定できちゃえば、行番号の特定は不要かも
改めてニーズのまとめ
- 出てきた全パターンを同じフローでカバーしたい
- 変数①:ラジオボタンオン入りtableの1行目の2列目のtextを取得したい
- 変数②:ラジオボタンオン入りtableの、ラジオボタンオンの行の3列目のtextを取得したい
- つまり、ラジオボタンオンの行のn列目のtextを取得したい
安心材料
- ひとまず「画像マッチング」でなら何とかなりそう
ほぼ同じ仕様の2システムが対象
この画面だけは両システムでtable内の列幅とか列数が異なる
それでも2パターンをカバーすれば、同じシナリオが使い回せる
思い
- 「画像マッチング」は最終手段のスタンスなので、使わざるを得ないのは悔しい
- このライブラリ中心のシナリオなので、なおさら悔しい
https://winactor.com/questions/question/教わりながら「ブラウザ操作配列のアクションを/
- 引き続き、既存ライブラリを組み合わせてクリアできる方法を模索したい
- 「ブラウザ操作配列のアクションを順次実行」のアクションに、ラジオボタンの値取得を組み込んだように、
https://winactor.com/questions/question/chromeのシナリオでtd内にあるラジオボタンオンの値を/
ラジオボタンオン入りtableの、ラジオボタンオンの行のn列目のtextを取得を組み込みたい - 実現できたら、ウチで同じシナリオの幹をシェアしてる範囲にとっては朗報
- 社内で同じシステムを使ってる人たちにも喜ばれるのかも
- ただ、これは汎用的なニーズではない、、
- このままだと、たとえ既存ライブラリの組み合わせて乗り越えられるヤマだとしても、参戦意欲が湧きにくいか、、
- わたしが逆の立場でも、「画像マッチング」で良いのでは?と言いそう、、
あえて表現を変えます。
- やっぱり「画像マッチング」でしかできませんか?
- ブラウザ関連ライブラリの組み合わせでは取得できませんか?
こう問われたら、わたしが登りたくなるヤマに大変身です。
(20220904追記)
ハードルを伝える用のサンプル.htmlを用意しました。
★周辺について、アイデアやアドバイスをいただけると幸いです。
「なんだ、たったそれだけでできちゃうのか」というオチな気がしてます。
サンプル.html
<!-- ※ メモ帳に貼り付けて「サンプル.html」として保存、テストしたシナリオ.ums7で開きます。-->
<html>
<head>
<title>サンプル</title>
</head>
<body>
<table border="1">
<tr class="x">
<td class="x"><input type="radio" id="1_1" name="a"></td>
<td rowspan="4" class="x">1B</td>
<td class="x">1C1</td>
<td class="x">1D1</td>
</tr>
<tr class="x">
<td class="x"><input type="radio" id="1_2" name="a"></td>
<td class="x">1C2</td>
<td class="x">1D2</td>
</tr>
<tr class="x">
<td class="x"><input type="radio" id="1_3" name="a"></td>
<td class="x">1C3</td>
<td class="x">1D3</td>
</tr>
<tr class="x">
<td class="x"><input type="radio" id="1_4" name="a"></td>
<td class="x">1C4</td>
<td class="x">1D4</td>
</tr>
</table>
<table border="1">
<tr class="x">
<td class="x"><input type="radio" id="2_1" name="a"></td>
<td rowspan="3" class="x">2B</td>
<td class="x">2C1</td>
<td class="x">2D1</td>
</tr>
<tr class="x">
<td class="x"><input type="radio" id="2_2" name="a"></td>
<td class="x">2C2</td>
<td class="x">2D2</td>
</tr>
<tr class="x">
<td class="x"><input type="radio" id="2_3" name="a"></td>
<td class="x">2C3</td>
<td class="x">2D3</td>
</tr>
</table>
</body>
</html>
<!-- 実際のidは連番ではない -->
ハードル
- nameが同じラジオボタンでも、tableを跨ぐと一気通貫でカウントアップできない(そう思い込んでる)
- 2列目が結合されてるから、各tableの2行目以降は//td[2]でヒットするのは3列目(値がCの列)になる
ハードル1.の深堀り
- //input[@name="a"]で7つのラジオボタンがヒットする
- 7つをカウントアップしながら「チェック状態取得」したい
- 通常は//tr[カウンタ]//input[@name="a"]を使おうと考える場面
- サンプル.htmlのようにtableが分かれてると、//tr[1]が一意でない、//tr[5]が存在しない
- table毎にチェック状態を調べることになるか
- tableは5とかもっとあることも
- できれば一気通貫でカウントアップしたい
- ★サンプルで言及できてない範囲で、たとえば何があれば一気通貫でカウントアップできる?
- 都合の良いdivとかはない、、
- 図解で言及してないのはclassの中身とng(AngularJS)系の属性(アクション?)くらい
- 各セルのtextはそれぞれlabel内にあるものの、labelは専らstyleの指定に使われてる、forはない
ハードル2.の深堀り
- ★//td[2]の値が目的の値①と一致する場合は//td[3]の値を目的の値②として採用することになるか
- ★たとえばXPathの記述の工夫とかで、もっとスマートに取得できないものか
- 2列目は//td[@rowspan]でスマートに取得できた
- ここみたいに複数パターンにマッチする記述が案外身近にあるんじゃないか
https://winactor.com/questions/?q=Chrome値の取得で両階層の別idに対応
テストしたシナリオ.ums7
ブラウザ起動:chrome
ページ表示:サンプル.html
グループ
変数値設定:カウンタ、1
後判定繰返:チェック状態 がfalse
文字列の連結(nつ)
値⇒//tr[
カウンタ
値⇒]//input[@type="radio"]
ラジオボタンのXPath
チェック状態取得:ラジオボタンのXPath、チェック状態
文字列の連結(nつ)
値⇒//tr[
カウンタ
]//input[@type="radio"]/../../..//td[@rowspan]
2列目のXPath
値の取得:2列目のXPath、目的の値①
文字列の連結(nつ)
値⇒//tr[
カウンタ
]//input[@type="radio"]/../../..//td[3] ← 2.の考察通り、ひとまず「分岐」で迂回が必要か、、
「3列目」のXPath
値の取得:「3列目」のXPath、目的の値②
作ってみた所感
- すべて考慮すればフロー自体は成り立ちそう
- 1つめのテーブルの3つめのラジオボタンをオンにした状態でグループの部分実行で4秒
([ログ出力]パレットの[経過時間]情報)
(うち、「文字列の連結(nつ)」から「値の取得」までは1秒) - 仮に5つめのテーブルだったら、、目的の値①のみの取得に単純計算で20秒かかる
(実際は「繰り返し」とかで若干のアドオンもあるはず) - ハードル2.がそもそもなかったとして、目的の値②も取得すると+1秒で21秒
- ハードル2.対策に「分岐」「文字列の連結(nつ)」「値の取得」を使うと1秒上乗せくらいか
- 1周4分かかってるシナリオを1分台に収めようと画策する中で、今回の追加ニーズで30秒弱のロス
- かなりイタイ
- もっさりのレベルを大きく上回る
- 「RPAってこんなものか」「WinActorってこんなものか」って誤解されたら切ないレベル
- ★目的の値①と②をもっと高速に快適に取得できないものか
- 我慢できるのは1table1秒、5tableなら5秒くらい
現実逃避案
- 「画像マッチング」で相対位置のトリプルクリック、Ctrl+C、「クリップボード」の値を取得にしちゃうかも
- 実測1秒弱、人の手作業と遜色ないスピード感
- 初回に、目的のラジオボタンより右下にある別枠のラジオボタンのほうにマッチしちゃった
- 怖い
- マッチング画像の赤枠をチューニングする必要がありそう
- //input[@name="a"]のラジオボタン入りのtableは、スクロールが必要なくらいの数が表示される可能性もあるとも聞いている
- リアルタイムマスクが活きる場面かも
https://winactor.com/questions/question/画像マッチングに邪魔な部分をリアルタイムマス/
ほかの方法
- どこかのスレッドで教わった、Edgeの[Web選択]相当、「表の一括取得」「テーブルスクレイピング」経由のほうが確実か
- でも、さらに別のスレッドで、結合セルのハードルにぶち当たってるのを見かけたし
- 表の全コピからのExcel貼り付けで、表と値は忠実に再現される
- ラジオボタンとかのコントロールが付いてこず、残念
現実案(暫定)
- 「画像マッチング」でしのぎつつ、XPathとライブラリの最速な組み合わせを模索する
- これが現時点のバランスポイントっぽい
目標:「ブラウザ操作(配列のアクションを順次実行)」に組み込むこと
- 既存ライブラリの組み合わせでも立ちはだかるハードル2つをある程度克服しておかねば
- アクションを[ラジオボタンオンの行のn列目のtextを取得]にまとめるとしたら、こんな設定になる見込み
アクション,チェックオンの要素のXPath,取得した値を格納する変数,取得する値がある列番号,取得する値の属性名
- 現行の5枠にギリギリ収まりそう
- チェックオンの要素のXPathは、最近作ったアクション[ラジオボタンのラベル取得]の一部を取り込むことになるか
「ブラウザ操作(配列のアクションを順次実行)」未体験のかた向けに概要の補足
- 「シナリオファイル呼び出し」から変数(引数)を4つ渡して[テストしたシナリオ]を呼び出して、戻り値を得る感じ
- 戻り値が目的の値①とか②
- あるいは、ローカル変数を4つ入りの「サブルーチングループ」を「サブルーチン呼び出し」、返り値を得る感じ
- 返り値が目的の値①とか②
- どっちもやったことない
- 戻り値とか返り値とかの用語って、意図的に使い分けられてるのだろうか
- あるいはVBA/VBSで、引数を渡してFunctionを実行、目的の値①に値を格納する感じ
Call 目的の値① (アクション, XPath, 列番号, 属性名)
- 約220項目を1分くらいかけて取得中、単純計算で3.6項目/秒
- 1ライブラリ内で配列の要素数分を繰り返す
- ノードの「繰り返し」に入れた場合の1ライブラリ毎のオーバーヘッドがない
(20220905さらに追記)
ハードル2.の続報
- ★特定したラジオボタンオンの行のtdで、rowspanがない、2つ目
- 安定的に指定する方法を見つけたかも
//table[1]//tr[2]/td[not(@rowspan)][2]
- ラジオボタンオンの行の〜の後が一定の表記で良くなった
- 初めてnotを業務で使用
- ★正解の1つっぽいけど、果たしてこれがベストな書きかたなのかどうか
- tableとtrの各position特定は、やっぱり既存ライブラリの組み合わせだと時間がかかる
tbody
- tbodyを書く習慣がなかったけど、最近のChromeはよしなに補ってくれるみたい
- おかげで追加で階層の意識が必要になって、//と省略するハメに
- tbodyがないtableはWinActorかWebDriverがうまく制御できない
- そんな情報をどこかのスレッドで見かけた気がする
ハードル1.の続報
- ダイタンな発想方面
- たとえば、すべてのtdの内側にdivを補っちゃえば道が開ける??
- JavaScriptで属性の書き換えを試す過程で、そのタグごと上書きしてみたことがある
- と思いきや、ハードル1.は乗り越えられそうもなかった
- それなら、途中のtable終了タグとtable開始タグをなかったことにしちゃえば道が開ける??
- 取得して置き換えて上書き
1つめのtable開始タグとラストのtable終了タグは残す - 手が届きそうな予感
所要時間の懸念
- 後日動作確認を経て勝算を見出せるかどうか
- JavaScriptの実行は、アドレスバーからでもConsoleからでもひと呼吸要する
- 1秒の「画像マッチング」に勝てるかどうか
≒一括の方法が見つかるかどうか - 対象の全テーブルを囲うdivとかがあれば、outerHTMLをガバっと掴めるはず
- 正規表現で置き換えるのは一瞬
- 途中のtable終了タグとtable開始タグをカットしたHTMLを戻すのも、やっぱりひと呼吸要するJavaScript
- 「画像マッチング」は何しろ1秒、強敵
- 5table分の繰り返しが必要なら到底勝ち目はない
1ライブラリの光
- でもこれが1ライブラリ化できたら、「画像マッチング」よりはずっと速いはず
- 1秒のせめぎ合い
- 既存ライブラリの最適なフローを特定でき次第、1ライブラリ化
- 1ライブラリ化さえできちゃえば、配列のアクションを順次実行に組み込むのは、作業時間を作れるかどうかだけ
- やっぱり今でも、ハードル1.と2.の最適解を欲してる、模索したい
コストの問題
- たった1~2項目の取得なのに、ほかの200項目に比べてかなり高コスト
- このWebシステムを作った側も、きっと相当工夫を凝らした箇所の1つに違いない
- 藁をもすがる思いでサンプル.htmlを試せるようにはしてみた
- 前進のきっかけになり得ると信じて
- かなり深く考えて
- でもきっと、今回の課題は「画像マッチング」を上回る方法はない
- 現時点で最新のVer.7.4.1をもってしても
- そう高をくくり始めた
- table跨ぎの一気通貫カウントアップが一縷の望みと予想してたけど
- こう書いちゃうと、アイデアが寄せられるきっかけを潰しちゃうことになっちゃうか
機能強化への期待
- 今後のアップデートで、自動記録に期待したい
- 「ラジオボタンがオンの行のn列目の値を取得」とか「ラジオボタンがオンの行のn列目の値を取得」になるようなXPathなりフローが生成される感じ
今日のところは一旦「画像マッチング」にしときました。
ごちゃごちゃ書いてきましたが、ハードル1.と2.の最適解方面、引き続きアイデア・アドバイスをいただけたら幸いです。