いつもやってるCSSセレクタの作成方法

RPAのCSをやっていて特によくいただく質問の1つに「Selector not foundが表示されてしまう」というものがあります。指定されているセレクタがWebサイト内で見つけることができなかったということ。

あまりにもこの質問が多いので僕がいつもどうやってこの質問に回答しているのかをお伝えしていこうかなと思います。Robotic Crowdユーザーに限らず参考になるかもしれません。

1. セレクタの基礎知識(要素/属性)

CSSセレクタを作成するときに理解しておくべきワードが3つあります。

・要素(タグ)
・属性
・値

CSSセレクタはこの3つを指定することで構成されます(最低限どれか1つは必要)。

1.要素名[属性=値]の形 ex) div[class="hoge"] または div[class=hoge]
2.要素名[属性]の形       ex) div[class]
3.要素名のみの形          ex) div

そもそも要素、属性、値とはなんのか?という話です。

<div id="main">
  <div class="list" name="list_1">
    <li label="1">
      <a href="/hogehoge/aaaaa">リンク1</a>
    </li>
    <li label="2">
      <a href="/hogehoge/bbbb">リンク2</b>
    </l1>
  </div>
</div>

こんなHTMLがあったとすると、下記のそれぞれが要素・属性・値です。

要素:「div」「li」「a」
属性:「id」「class」「name」「label」「href」
 値 :「main」「list」など属性の値

2. セレクタの基礎知識(親子要素/兄弟要素)

CSSセレクタを作成する際に理解してきたいHTML階層に関するワード。

・親要素
・子要素
(・兄弟要素)

HTMLはマトリョーシカみたいな感じで箱の中に箱が入っている入れ子構造になっています。下記のサイトがとてもとてもわかりやすいです。

https://webliker.info/26463/

親要素:囲っている側の要素
子要素:囲っている箱の中(直下)にある要素
兄弟要素:同じ階層にある要素

フォルダのディレクトリとかをイメージしてもらえると理解しやすいかなと思いますが、このあたりの概念はちょっと難しいかもしれません。

CSSセレクタでは親要素と子要素の関係を「>」で示します。
「>」の左側が親要素、右側が子要素を指していて、div > aであればdivの直下にあるa要素を指します。下記のHTMLであればhoge1とhoge2どちらもこのセレクタに一致します。

<!--親要素-->
<div>
  <!--子要素たち-->
  <a>hoge1</a>
  <a>hoge2</a>
</div>

隣接要素(兄弟要素の中で隣同士になっているものだけ)の関係は「+」で示します。div > a + aであればhoge2の部分だけを指し示すことになります。

3. セレクタの確認方法

document.querySelector("【セレクタ】");

「右クリック→検証→console」にこのコードを入力する、以上です。

マネーフォワード_クラウド経費APIドキュメント

入力するとこんな感じで一致した要素が表示されます。コードで表示されるだけでなく実際のサイトも該当の要素が選択状態になります。

画像3

一致する要素がない場合には「null」と表示されます。

note_――つくる、つながる、とどける。

あとは一致するまで総当たりでいろいろと入力していきます。
総当たりする方法①は末端の子要素から徐々に階層を戻っていく方法
方法②は確実に取れる親要素から徐々に階層を掘っていく方法

僕は①でまずはやってみて、全然わかんねぇなと思ったら②に切り替えます。

4.セレクタ作成の優先度

安定性(より確実にセレクタを取れる)がRPA稼働時にはとても大事です。
なので自作でセレクタを作るメリットは自分の目で安定しているかどうかを判断しながら作れる点にあると思っています。

①該当要素のidまたはnameまたは要素名

真っさらの状態から最初に入力する一番確実な指定はidかnameです。

idはHTML全体の中で1つしか同じ値を指定することができません。nameも同様です。idかnameの属性を持っている要素であればこれだけでセレクタ作成が完了します。<div id="main">であれば#main(#はidを示しています。)、<li name="list_1">であればli[name="list_1"]がそれぞれ完成したセレクタです。

idやnameが振られていない場合はとりあえず要素名だけ入れます。

<注意点>
・idやnameがあっても乱数(ランダムな英数字配列)になっている場合がよくあります。その場合もとりあえず要素名だけを入れましょう。サイトにアクセスする度に値が変わっている可能性があります。
・極稀にid、nameで同じ値が使われていることがあります。

②id,name以外の属性値

idやnameがないときはサイト全体で1つしかなさそうな属性と値を探してみます。labelやdata-idやvalueの値などなどサイト内に1つしかなさそうな値を見つけたらとりあえず入力して確認します。

サイト内に1つしかなさそうな」というところが重要で、たとえば<input title="今日の日付">という要素があれば、『今日の日付を入力する欄は1つしかなさそうだからinput[title="今日の日付"]でいけそうだな。』と推察できます。重複があれば別の属性と値を指定します。

③子番号を入力

サイト内に1つしかない属性値がなかった場合「:nth-child(n)」を使い、子番号で指定できそうかを見てみます。<option>とか<li>とかのリスト形式、<div>なんだけどリスト形式になっている時は結構便利です。

<注意点>
子番号番号が変動して困る場合には使わない方が安全です。『必ずn番目を指定したい』というときは問題ないですが、『必ず特定の要素じゃないとダメだ』という場合には使わない方が良いでしょう。

④親要素を指定

③までやってみて欲しい要素と一致しない場合には親要素を指定します。
手順は①〜③と同じです。一致したら「>」で親要素と子要素を繋ぎます。

親要素も一致しなければさらに上の親要素、なければその上の親要素・・・と階層を遡って、それぞれを「>」で繋ぎます。

この時、子要素になる方にclass属性がある場合には、classの値を指定しておくのが安全です(場合による)。<div class="hoge">はdiv.hogeと記載し、ドットがclassを示しています。めちゃくちゃ長いclassや、ランダムっぽいclass、HTML内で同じclassがすごいたくさん使われている時には無理して使わなくていいです。

⑤兄弟要素で指定

親要素でもなかなか一致しないことは往々にあります。一致はするけどめちゃくちゃ長いセレクタになることもよくあります。そんな時兄弟要素の指定も便利です。

<div id="hoge">
  <span>こんにちは</span>
  <a href=/aaaa>こちら</a>
</div>

「span + a」と書くとspanの隣のa要素を指定できます。
(①〜④の手順に沿うなら#hoge > aが最適)

⑥途中のセレクタを省略

一致するセレクタが完成した後、途中を省略することもできます。「#hoge > div > div > div > div.list > a」みたいなセレクタを「#hoge div.list > a」のように「>」ではなく半角スペースで繋ぐことで#hogeの子孫要素全体の中のdiv.list直下のa要素という指定になります。

「>」は直下の子要素のみ、半角スペースは子孫要素全体を指しています。

5.まとめ

今まで感覚的にやってたことを言語化してみました。
抜けてるところあれば随時追加していこうと思います。

<理解しておくべきこと>
・HTMLの要素/属性
・HTMLの親子要素の関係
<CSSセレクタの作り方>
・id、nameがあれば一番確実
・HTML全体で1つしかなさそうな属性値を探す
・親要素を遡っていけばいつかは見つかる

ざっくりとまとめるとこんな感じ。質問とかあればTwitterにメッセかリプください。

この記事が気に入ったらサポートをしてみませんか?