iPhoneでスクレイピング（ショートカットアプリ）

# はじめに
iPhoneにはショートカットと呼ばれるアプリがあり、これを使うとiPhoneで行ういろんな作業を自動化することができます。これでできることの一つにURLを指定してHTTPリクエストを送る機能があり、今回はそのレスポンスをパースする作業を説明してみます

またHTTPリクエストを送るだけでなく、iOSのSafariを開いてそのページで任意のJavascriptを実行することも可能です。この場合はSafari開く部分で操作が必要になるため、完全な自動化はできません

作ったショートカットはオートメーションに設定することで、毎日任意の時刻で自動実行が可能になります

今回はYahooJapanのトップページから主要ニュース一覧を取得するショートカットを作ってみます

- 使用するアプリ

https://apps.apple.com/jp/app/%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/id915249334

- 使用したiOS: 14.6

# HTMLのみをスクレイピングする方法

実際に作ったものはこちらです。実行すると主要ニュース部分をスクレイピングしてアラートに表示します

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/77eea952-d0a4-2d15-33d3-bc17cbfaedc4.gif)

https://www.icloud.com/shortcuts/1065b9e87b99411db82b39e7259e1fe5

## 作り方

ショートカットの新規作成時の画面です。この「アクションを追加」からアクションを追加していくことでショートカットを組み立てていきます

![Image_20210530_210507.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/630f2b92-c766-b7d4-7431-85c54e00e91c.jpeg)


まずは「テキスト」を追加し、そこの対象のURLを入力します。次に「変数を設定」を追加し変数`url`に上記で入力したURLを設定します。今回はわざわざ変数にする必要はありませんが、変数にしておくと文字列の結合などが必要になったときに汎用性が高く使うことができます

![Image_20210530_210511.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/f0819778-5255-941f-30ec-79edb404661f.jpeg)

このショートカットアプリでは前の出力を入力の引数として用いたい場合、マジック変数を入力に選択して対象の変数を選択します（ここでは「テキスト」）
![Image_20210530_210525.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/5bd55fa1-cd63-a47a-fa57-7aaf102a26b8.jpeg)

次に「URLの内容を取得」を追加します。このアクションはあらゆるHTTPリクエストをヘッダー付きで行えるため、例えばAPIサーバーへのアクセスや自動フォーム入力でログインなどもできるようになります。ここではこのままの設定でGETでリクエストを送ります

![Image_20210530_210514.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/3dcfdba1-7a5e-490a-091a-27edcf6bfb74.jpeg)

次に「リッチテキストからHTMLを作成」を選び、「URLの内容の取得」の結果である「URLの内容」を入力に設定します。この結果が今回のURLのHTMLの文字列となります

![Image_20210530_210517.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/80cc10d8-0c9b-2a93-72a3-0c0b90b92060.jpeg)

ここからはHTMLのパースになります。プログラミング言語にライブラリとして存在しているようなパース用のライブラリがあるわけではないので、この部分は正規表現のマッチングと文字列の置き換えで欲しい情報まで変換していく作業です

「一致するテキスト」を用いて必要な箇所を抽出、抽出された文字列から「テキストを置き換え」で不必要な部分を省くという手順で、ニュースの内容を抽出しています

![Image_20210530_210520.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/26b767c6-919c-4081-f387-798260e56285.jpeg)


![Image_20210530_210523.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/2ab94e53-24b4-608f-1686-0bcae2f260ef.jpeg)

最後にこの結果を「アラートを表示」の入力にすることで、ニュースの一覧をアラートにして表示しています。例えば、この部分を「ツイート」に変えることでスクレイピング結果をツイートすることができる、といった具合に応用ができると思います

![Image_20210530_210527.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/decb3b90-1488-9df9-d914-b13909f7f013.jpeg)

以上でYahooの主要ニュースアラートのショートカットができます

# Safari + Javascriptでスクレイピングする方法
ここまではショートカットアプリ内で完結できますが、ショートカットを共有シートに表示させることで別のアプリから入力を受け取るなどが可能になります。その一つとしてSafariで開いたページを渡してJavascriptを実行するということも可能です（逆に言うとSafariから実行する必要があるためその部分が手動になってしまいます）

![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/e3f1c2ae-ec29-8191-5b46-a8f533d2925d.gif)


ここでは、対象のURLをSafariで開くショートカットとSafariからJavascriptを実行するショートカットの2つを作ります

- 1つ目

https://www.icloud.com/shortcuts/72ac067d07ea4c15b6baa4003d231f34

- 2つ目

https://www.icloud.com/shortcuts/4667899fc23940b9a98ad9f6e949ed04

## 作り方

1つ目のSafariの「Webページを表示」でURLを開くまでのショートカットを作ります

![Image_20210530_215422.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/4147ab24-2a0b-94b1-b1cc-ee0e0d8fe1b8.jpeg)

2つ目のSafariで開いた状態で行うショートカットを作ります。このショートカットはSafariの共有から実行する必要があるので、詳細設定の「共有シートに表示」をオンにして「SafariのWebページ」を選択しておきます

![Image_20210530_215419.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/f35b431c-1bcc-4557-59df-703a51ff204e.jpeg)

「WebページでJavaScriptを実行」を追加して、実行したいJavascriptを入力します。ここではcssクラスとh1タグからテキストを抽出しています

![Image_20210530_215417.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/019bc1c7-376a-515d-a58d-6ac0b35ccb1a.jpeg)

（入力したJavascript）

```javascript
var result = [];

var elements = document.querySelector(".TopicArticles").querySelectorAll("h1");

for (let e of elements) {
   result.push(e.innerText);
}

completion(result);
```

最後にこの結果をアラートで表示します

![Image_20210530_215414.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/85b4b878-0618-4992-dd44-b2ef839114a1.jpeg)

# おわりに
全部iPhoneで入力しないといけなかったり、正規表現を使わないといけなかったりと結構面倒ですが、iOSの機能だけでスクレイピングしてその結果を他のアプリに利用できるので使いみちはありそうですね