CSSセレクターを使いこなす : Power Automate for desktopがなんとなく使える講座 #12

（この記事は、2022/01/03に執筆しました）

この記事の前提条件。

- HTMLが何か知っている
- CSSが何か知っている
- Power Automate for desktopでWebページからデータを抽出したことがある

**※参考:** サンプルで使用したWebページは、以下のアドレスになります。
[https://fukuyori.github.io/RPALT20220117/](https://fukuyori.github.io/RPALT20220117/)

# 01.CSSセレクターとは
　CSSでデザイン定義を行う際、定義する場所を指定する記述方法です。Automation AnywhereではXPathを使ってWeb上の場所を指定しますが、Power Automate for desktopでは、CSSセレクタを使います。CSSを自分で書ける人は、以下のドキュメントを確認してください。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Selectors

　また、jQueryのセレクタ機能も使っています。

http://www.jquerystudy.info/reference/selectors/


## CSSセレクタの取得
　GUIでWeb上のデータを取得する場合、以下のようにHTMLタグが連なって表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/81edfe77-00f9-abe1-22d0-493fbdf5551b.png)

```css:CSSセレクタ
html > body > div:eq(0) > div > div:eq(1) > div:eq(0) > p:eq(0)
```

　Power Automate for desktopのGUIではなく、ブラウザ(Microsoft Edge)の機能を使ってセレクタを取得することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/46269acd-4637-9bcf-b000-47e46b4a8474.png)
　取得したい箇所を右クリックし、「開発者ツールで調査する」を選択。HTMLのコードが表示され、該当の個所がハイライトしていますので、その箇所で右クリックして、「コピー」⇒「selectorをコピー」とします。
　Chromeを使用している場合は、「開発者ツールで調査する」は「検証」になります。

```css:CSSセレクタ
#FirstLetter > p:nth-child(1)
```

　Power Automate for desktopで取得した場合より、すっきりしています。CSSセレクターについて、少しわかるようになると、簡潔で、より柔軟性の高いCSSセレクターを記述できるようになります。

**※注意：**抽出プレビューでは、子要素のデータが表示されないことがあります。一度実行した後、変数の中を見て確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/997a84a7-a31b-d8d9-95c7-dcd18b114e09.png)

# 02.「Webページからデータを抽出する」
 Power Automate for desktopの「Webページからデータを抽出する」のアクションで、以下の詳細設定ができます。

## 抽出形式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a08b6189-f310-10e3-27a5-98cefed97661.png)

|名称|説明|
|--|--|
|未定義|データを取得しません|
|単一の値|1つの値を取得します|
|選択した値|セレクタを複数指定して取得|
|リスト|リスト形式で取得|
|テーブル|テーブル形式で取得|
|HTMLテーブル全体|tableタグの内容をテーブル形式で取得|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a40149be-42a1-306d-516c-10bb35d4d00d.png)
### 「選択した値」で取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/5ce4f3f3-7e2f-e50e-de98-aa86bcf7c297.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/bebd988e-3d7a-067b-499a-784d49886b13.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/598e76a2-0d00-9ebb-d4d7-74e308fa72bb.png)
### [リスト」で取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/01bc2980-4baf-7ebe-7908-5bed212665a6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/984ef162-48b4-6725-7f51-d30be53d6cda.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ff3c1308-9ef4-fa46-54c2-b731b6267a01.png)
### 「テーブル」で取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/718a020f-907f-f4f0-a72b-0840780fea59.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7a0b5924-39d6-bac9-ed8f-5b4184cbdf4d.png)
　テーブルや、リストで抽出するとき、基本CSSセレクターの指定する場所は、繰り返しが発生する場所です。そのあと、CSSセレクターで各項目の内容を指定してやります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/9ebcb0dd-9a91-d98d-3457-3c0c85551591.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/49304f29-f333-492b-76eb-8d05fd8f9234.png)
### 「HTMLテーブル全体」で取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2bd3c22d-6898-cca0-c187-2cd4765f5186.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/01f3dbb7-bfef-288b-39a5-8e30e91a3f39.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6ceb5a88-63f3-26bc-3cee-8f96e9442758.png)

## 属性と正規表現
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/0511ceed-7a74-00dc-5a5e-501c221ff3dc.png)
　属性は、タグで囲まれた中の文字列は **Own Text** で取得できます。タグの中に書かれた属性の値を取得する場合は、その属性の名前を書きます。
　取得する値は、正規表現を使って整形することができます。「100円」となっている場合は「\d+」と指定すれば、「100」と、数字だけの値を取得することができます。
　正規表現の書き方は、以下を参照してください。

https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference

# 03.セレクター、結合子、フィルター

## セレクター
　自分で作成したWebページであれば、必要な場所に自分でタグを設定できますが、公開されているWebページは、利用しやすい形になっていません。目的の項目を見つけるには、HTMLタグを手繰って探るということをやります。その時使うのは、セレクターと結合子です。

|名称|説明|例|
|:--|:--|:--|
|全称セレクター|すべての要素|*|
|要素型セレクター|要素名を指定|input|
|クラスセレクター|class属性を指定|.classname|
|IDセレクター|id属性を指定|#idname|
|属性セレクター|属性を指定|[attr] [attr=value]|

　使用する優先度は、IDセレクター、要素型セレクター、クラスセレクター、属性セレクターの順番です。
　IDセレクターは、原則として１ページ上でユニークになっています。原則に従っているページなら、IDが設定されている場所へ間違いなく飛ぶことができます。ただし、あくまで原則なので、IDが重複しているページもあります。その場合は、前後のタグの構造を確認する必要があります。
　クラスセレクターが項目の内容を示す書き方（例えば、class="MemberList"のような意味のある単語が使われている）になっている場合、比較的安心して使用できます。しかし、大抵のページでクラスはデザインのために使われており、多数のクラス名が並んでいることが多い（例えば、class="css-1dbjc4n r-hvic4v r-1d2f490 r-1xcajam r-zchlnj r-1ykxob0"）ので、その場合は使用しない方がいいでしょう。
　属性セレクターは、IDセレクターやクラスセレクターの選択に条件を付けたり、それ以外の属性を指定する場場合に使います。指定方法の詳細は以下のようになります。

|構文|説明|例|
|:--|:--|:--|
|[attr]|その属性を持つ要素|[name]|
|[attr=value]|指定された属性の値が完全一致<br> [class="a b c"]は<br>class="a b c"と一致|[class="bold-01"]|
|[attr~=value]|[class="b"]は<br>class="a b c"と一致|[class~="red-02"]|
|[attr&#124;=value]|[id&#124;="pre"]は<br>preとpre-viewと一致|[class&#124;="red"]|
|[attr^=value]|要素の最初の値に一致|[class^="bold-02"]|
|[attr$=value]|要素の最後の値に一致|[class$="red-02"]|
|[attr*=value]|[id*="re"]はpreとrenと一致|[class*="old"]|
|[attr operator value i]|値の大文字と小文字を区別しません|[class$="LISTITEM1" i]|
|[attr operator value s]|値の大文字と小文字を区別します|[id="ListItem1" s]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3471b769-7658-4e13-06ec-f42af461f5d4.png)

　**^=** は、属性の値の先頭からの一部分で一致します。**a[href="https"]** では、リンク先のURLがhttpsのものを選択することができます。しかし、**$=** は、値の末尾の部分一致はできないようです。**a[href$=".com"]** は動作しません。代わりに**a[href*=".com"]** で部分一致をさせることができます。

## 結合子
　目的のデータを取り出すには、セレクタ、結合子、フィルターを使っていきます。出来るだけ、曖昧さのない、Webページの変更の影響を受けにくい組み合わせを見つけることがキモになります。

|名称|構文|説明|例|
|:--:|:--:|:--|:--|
|子孫結合子|A B|子孫にあたるノード|#MainContent p|
|子結合子|A > B|直接の子のノード|#MainContent > div > p|
|一般兄弟結合子|A ~ B|Aの後にあるBの要素|p ~ p|
|隣接兄弟結合子|A + B|Aの直後のBの要素|span + p|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a44b4c59-1ac3-0b28-f282-3486ee69f8c9.png)

## jQueryのフィルター

|構文|説明|例|
|:--|:--|:--|
|:first|最初の要素|h3:first|
|:last|最後の要素|h3:last|
|:even|偶数番目の要素|
|:odd|奇数番目の要素|
|:eq()|指定したインデックス番号の要素|h3:eq(0)|
|:lt()|指定したインデックスより小さい番号の要素|h3:lt(1)|
|:gt()|指定したインデックスより大きい番号の要素|h3:gt(1)|
|:not()|動作未確認||

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c9f5c861-596e-2247-5032-9720c891d5be.png)
### even
　偶数番目の要素ですが、0から始まるので、選択されるのは、１と３です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/31614872-8f7c-d3c8-1c5a-1dcf9e9d536b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1ed947c5-a1dc-3569-c2c1-9bbd2812c11c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/83ecc447-40d6-4a81-97d8-d8874c4fc476.png)
### odd
　奇数番目の要素ですが、0から始まるので、選択されるのは、２と４です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1a2b3908-1922-4a12-b63d-f6276e27a8e4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/aeaeefdf-7bcb-5a42-2b91-42f5a6176bb4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3ef49332-2a06-76a1-6bec-21db5b6467d4.png)
### eq()
　番号は、０から始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f0bbbf94-d023-a415-c716-dd31e1154456.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c9f5c861-596e-2247-5032-9720c891d5be.png)
### lt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a059d044-8cb8-db71-e773-49c92aa26b53.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/aed3c4f1-59ee-f667-4b9b-40f251fdebca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/5cc7dfa4-9e24-5514-9621-1abea138b655.png)

## jQueryの子要素フィルタ

|構文|説明|例|
|:--|:--|:--|
|:first-child|最初の子要素|#Table-1 > tbody > tr > :first-child|
|:first-of-type|セレクタで指定された<br>最初の子要素|#Table-1 > tbody   td:first-of-type|
|:last-child|最後の子要素|#Table-1 > tbody > tr > :last-child
|:last-of-type|セレクタで指定された<br>最後の子要素|#Table-1 > tbody   td:first-of-type|
|:only-child|子要素が<br>１つだけのときに取得|
|:only-of-type|セレクタで指定された要素が<br>１つだけのときに取得|
|:nth-child()|親要素内にあるセレクタで<br>引数で指定した要素|#FirstLetter > span:nth-child(2)|
|:nth-of-type()|セレクタと引数で指定された要素|#FirstLetter > p:nth-of-type(2)|
|:nth-last-child()|nth-childを最後から数える|#FirstLetter > :nth-last-child(2)|
|:nth-last-of-type()|nth-of-typeを最後から数える|#FirstLetter > span:nth-last-of-type(2)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)
### first-child
 最初の子要素を取得。セレクタを指定した場合、１番目の子要素に一致しない場合は取得できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2ed25f37-9fa6-4827-9e6c-7e950c3ec3cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/98bcc221-5827-ba39-b790-7463746fbcda.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/5f426389-82bd-fa2e-b0f3-ca388a64aa17.png)
### first-of-type
　first-childと異なり、最初の子要素でなくても取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/88211c84-9d7d-160c-14b6-2d820a4e7a1e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/62dc2257-7367-6460-9c87-ec16a6980605.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)
### nth-child, nth-of-type
　最初のセレクタを１として数えます。**【注意】:eqの場合は、0から始まります。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/0100933f-fbb8-4843-a877-3ae716aca518.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)
### nth-last-child, nth-last-of-type
　最後のセレクタを１として数えます。※図ではnth-child, nth-of-typeになってますが、nth-last-child, nth-last-of-typeの誤りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/8544244e-1d6e-4dd4-370c-46c714d50bf0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)

## jQueryのコンテンツフィルタ

|構文|説明|例|
|:--|:--|:--|
|:contains()|引数で指定した文字列を含む要素|#rsltlst > li:contains("ルート")|
|:has()|指定したセレクタを「子孫要素」に持つ要素|li:has(span)|
|:empty|Own Textが何もない要素|div:empty|
|:parent|動作未確認||

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)
### contains
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/06108299-c39d-3037-b93d-d2720d43f427.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/510d42fc-6c9f-35fa-50b4-922d4b765cbc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)
### empty
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/852e3ad9-d847-d027-e036-b2c0c6369421.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7e6cfe84-2376-1943-b5ff-30a548bed15e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fb8072a1-2932-61c4-83ac-b39814471104.png)