要素内の1つ目のテキストを変数に掴みたい
※ JohnさんコメントのXPathテスト結果を追記しました
ブラウザ操作のシナリオです。
要素内1行目だけを取得したいです。
どうすれば最速で取得できるでしょうか。
お知恵を拝借させてください。
環境
- WinActor720 or 740
- Chrome9x
- WebDriver制御
HTML
<td id="a">
<span>
あいうえお<br>
かきくけこ<br>
さしすせそ
</span>
<span></span>
</td>
実現したいこと
- 「あいうえお」だけを変数に格納
2、3行目込みだと残念な背景
- 安定性/正確性はもちろん、スピードが求められる処理なので、なるべくなら僅かでもタイムロスしたくない
- 後続作業のExcel関数等で除去しなくて済むようにしたい
核心に迫る情報
- ConsoleのElementsでn行目のハイライトに成功したXPath
//td[@id="a"]/span/text()[n]
仕様の認識
- text()はWinActorでは[ ]内で使える
(確か[ ]外で使えたケースもあった)
「値の取得」「属性値の取得」「プロパティ値の取得」の結果
- いずれも「指定された要素が見つかりませんでした。」
暫定措置
- spanのinnerTextを「属性値の取得」、加工して改行前までを得る予定
加工用ライブラリの候補
- 文字列を前後に分割
- 文字列を3つに分割
- 文字列分割
- 正規表現(文字列抽出)
- 正規表現(文字列置換)
理想の追求
- どんなXPathなら「あいうえお」だけを取得できるでしょうか
想定ライブラリ
- 値の取得
- 属性値の取得
- プロパティ値の取得
このへんで学んだことを総動員して試行錯誤してみたものの、クリアできずにいます、、
span要素のメンバーを区切り文字付きで取得したとしても、加工用のライブラリを登場させざるを得ないか、、
1つめだけを変数に格納すれば良いのか??
時間を見つけて試す予定
仮にこれでクリアできたとしても、既成ライブラリの範疇に収めたい欲が抑えきれず、、
Consoleでの確認状況
- すでにピンポイントでハイライトに成功するXPathを割り出し済みにつき、あくまでも参考程度
$x('//td[@id="a"]/span[1]')
要素がヒットする
- innerHTML:spanタグなし、改行部分が<br>
- innerText:spanタグなし、改行部分が\n
- outerHTML:spanタグあり、改行部分が<br>
- outerText:spanタグあり、改行部分が\n
- textContent:spanタグなし、改行相当なし
$x('//td[@id="a"]/span[contains(.,"span内のテキストの一部")]')
$x('//td[@id="a"]/span[contains(text()[1],"1行目のテキストの一部")]')
$x('//td[@id="a"]/span[contains(text()[2],"2行目のテキストの一部")]')
$x('//td[@id="a"]/span[contains(text()[2],"3行目のテキストの一部")]')
- いずれもspanまでのXPathと同様、きれいなouterHTMLの応答あり
- span前後の書きかたを工夫して、WinActorでも解釈してもらえる表記に仕立て上げられないものか
2022/12/22追記
Johnさん案のXPath、(//td[@id="a"]/span/text())[n] も、
//td[@id="a"]/span/text()[n] と同じく、
n行目がハイライトされました。
「値の取得」等では、やはり要素が見つからず。
触発されて、改めてXPathチートシートを確認
http://aoproj.web.fc2.com/xpath/XPath_cheatsheets_v2.pdf
軸周辺をテスト
//td[@id="a"]/span/child::*[1] → 1つめの<br>
//td[@id="a"]/span/descendant::*[1] → 1つめの<br>
//td[@id="a"]/span/descendant-or-self::*[1] → 2つの<br>
//td[@id="a"]/span/br/descendant-or-self::*[1] → 2つの<br>
//td[@id="a"]/span/descendant-or-self::*[1] → <span>
//td[@id="a"]/span/self::*[1] → <span>
//td[@id="a"]/span/following::*[1] → <span></span>
▼ チートシートより
text()ノード中の文字列。
例: <k>こんにちは</k>の中の 'こんにちは'
- どうやらtext()[1]はノード未満ってことみたい、、
▼ 悪足掻き
//td[@id="a"]/span/descendant-or-self::text()[1]
(//td[@id="a"]/span)/descendant-or-self::text()[1]
//td[@id="a"]/span/descendant::text()[1]/.
(//td[@id="a"]/span/descendant::text()[1])[1]
- いずれもn行目のハイライトには成功する
//td[@id="a"]/span/*[1] → 1つめの<br>
//td[@id="a"]/span/*[1]/following-sibling::* → 2つめの<br>
//td[@id="a"]/span/*[1]/preceding-sibling::* → ヒットせず
▼ 一縷の望み
- ブラウザ関連ライブラリで[ ]外でtext()が使えた例を参考にすることくらいか
2022/12/23追記
スクリプトの加工でも、目指したい地点に辿り着けるかもしれないと考え始めました。
- 「値の取得」を、要素の値に加え、nつ目のテキストも取得するように加工
空想段階、未リサーチ、未着手です。
「そんなのこーすればいーだけじゃん」な情報があれば教えてください。
- テキストを分割して配列にブチ込む
- nつ目のテキストを変数に格納
- 何とかなりそう
- DevToolsでXPathのtext()[n]ハイライトと一致がベター
- 改行のほか、スクリプトとかでブチ込まれたっぽい各テキストも、確かそれぞれの[n]のはず
- 改行系タグはないけどElements内では改行されてて、各行のテキストがダブルクォート内にある
- 改行、独立テキスト以外のパターンもあり得るのだろうか
- 発見次第追加考慮が現実的か
- 加工に適した既製ライブラリが複数ある
- 一括加工の工程を増やしてうまくいきそうでもある
- 例外は少ないに越したことはない
- 汎用性が高くて使い回せるのが理想
- 使い回す機会がどれだけあるか
- これができて使い勝手が良いならあれもできそう
- そんな発展形に繋がれば
好みの域です。
もし「値の取得(テキストn)」ができたら共有します。
わたしの使いかたは「値の取得(テキストn)」をアクションに追加です。
https://winactor.com/questions/question/教わりながら「ブラウザ操作配列のアクションを/