BOOTHからサムネを正規表現で自動取得してリストに貼り付けるやつ

#アバターリスト

　実は私は[「VRCで使える有償アバター一覧」](https://docs.google.com/spreadsheets/d/1bOLeSVe-hoPNsZzcwmnEo04JYjTws9bod3nNSw1Ja4I/edit#gid=0)というGoogleスプレッドシートを公開して、現在販売されているアバターをそこにまとめています。

　もちろんすべてのアバターを網羅できている訳ではないですけど、BOOTHを中心にまとめた結果現在では**100体**を超えていますので、それなりのデータは用意できているのではと思います（共同編集してくださる方にも、この場を借りてお礼申し上げます）。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">VRCで使える有償アバターリストに、試験的にサムネイルを追加しました。リストをそのまま貼り付けるとあまりにも縦長になるので、とりあえずサムネだけ抜き出したものを画像にしときます。<a href="https://t.co/ENXUzGLGND">https://t.co/ENXUzGLGND</a> <a href="https://t.co/jk56lernzw">pic.twitter.com/jk56lernzw</a></p>&mdash; Hibit (@hibit_at) <a href="https://twitter.com/hibit_at/status/1045643699252674560?ref_src=twsrc%5Etfw">2018年9月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#人力の限界

　ただ、100体を超えてくるとさすがに縦長のデータを見せられてもなんのこっちゃという感が強くなってくると思うので、サムネイルをつけようと思いました。サムネイルはBOOTHの販売ページにありますが、それを人力でコピーして……とやるのは非現実的です。他にも色々入力・保守で大変なことがありまして、人力の限界を感じつつあるこの頃です。

　ここはGoogleAppsScriptと正規表現に頑張ってもらいましょう。

#一部引用の明記

　本記事を書くにあたっては、[[GAS] Webスクレイピングで価格comから最安値を取得する](https://jidouka.work/?p=294)を参考にさせていただき、コードの大本も流用させていただきました。ありがとうございます。

#ソースコード

　とりあえずソース見せろという方へ。

```javascript
function myFunction() {
var aBook = SpreadsheetApp.getActiveSpreadsheet();
var aSheet = aBook.getSheetByName("test")
var lastRow = aSheet.getDataRange().getLastRow();
for (var i = 2; i <= lastRow; i++) {
  var url = aSheet.getRange(i, 1).getValue();
  var response = UrlFetchApp.fetch(url);
  var html = response.getContentText('utf-8');
  var regex = new RegExp("title\>(.*?)\-");
  var avatarname = html.match(regex)[1];
  var regex = new RegExp("\- (.*?)BOOTH");
  var shopname = html.match(regex)[1];
  var regex = new RegExp('image" content="(.*?)"');
  var imagename = html.match(regex)[1];
  aSheet.getRange(i, 2).setValue(avatarname);
  aSheet.getRange(i, 3).setValue(shopname);
  aSheet.getRange(i, 4).setValue('=Image("' + imagename + '",2)');
}
}
```

#導入

![image.png](https://qiita-image-store.s3.amazonaws.com/0/288125/ef580c21-f82a-4ec6-7352-0b7be847041c.png)

　念のため、導入を補足。「ツール」の「スクリプトエディタ」を選択するとエディタが出てきます。ExcelのVBAみたいですね。

#URLからソースを取得

　データ取得用のシートを別に用意して、その1列目にURLを列挙していきます。リンクが切れていたり、BOOTH以外のページだったりするとプログラムが止まってしまうので、そういった調整もしておきます。

```javascript
  var url = aSheet.getRange(i, 1).getValue();
  var response = UrlFetchApp.fetch(url);
  var html = response.getContentText('utf-8');
```

　1列目にあるデータを`url`として取得して、更にそのソースを`html`として取得します。なお、元コードではエンコードは`'SHIFT-JIS'`でしたが、`'utf-8'`にしないと文字化けするので今回はそうしています。

#正規表現でデータを取得

　BOOTHのソース
![image.png](https://qiita-image-store.s3.amazonaws.com/0/288125/df535189-04ce-d198-b569-08a4bffde8ae.png)
　にある黄色の箇所が抽出したい情報です。（とりあえず一番最初に登録した[アヌビスちゃん](https://takewaka.booth.pm/items/941368)のソースを使わせていただきました。takewakaさんごめん！　こんなにかわいいアヌビスちゃんがなんと2,500円！　買うしかない！）

　これを以下の正規表現で抽出します。

```javascript
  var regex = new RegExp("title\>(.*?)\-");
  var avatarname = html.match(regex)[1];
  var regex = new RegExp("\- (.*?)BOOTH");
  var shopname = html.match(regex)[1];
  var regex = new RegExp('image" content="(.*?)"');
  var imagename = html.match(regex)[1];
```

　`avatarname`はアバターの名前です。タイトルタグで囲まれており、ハイフンで区切られているので、
**「title>」　～（任意の文字列）～　「-」**
　の正規表現で抽出します。なお、`(.*)`ではなく`(.*?)`にしているのは最短一致にするためです（最初わからなくてハマった）。

　`shopname`はサークルの名前です。「-」と「-」で囲まれているので、一番始めに一致するのはサークルの名前になるはず……だったのですが、なんとBOOTHのタイトルタグには「サークル名がつかない場合がある」という謎の仕様があるので、これだとマッチせずにエラーを吐いてしまうことが発覚しました。なので、苦し紛れの策として、
**「-」　～（任意の文字列）～「BOOTH」**
　の正規表現で抽出します。余計なハイフンがついてしまう例もあります（というかそれがほとんどです）が、エラーなしで抽出するにはこれしかなかったんや……。

　`imagename`はサムネのパスです。ソースコードでは「image" content="サムネのアドレス"」という文字列になっているので、
**「image" content="」　～（任意の文字列）～　「"」**
　の正規表現で抽出します。絶対にもっとエレガントなregexがある気がしますが、動けばいいんだよ動けば。

　ちなみに抽出しといて何ですが、avatarnameとshopnameは余計なタグがついてたりshopnameが抜けていたりするので使いません。ていうか、今まで人力でまとめてたアバター名（よりわかりやすい）があるし。今後、アバターの名前をまとめるのすら人力では億劫になってきたらもっと工夫するかもしれません。

#サムネをシートに貼り付け

　後は抽出したサムネをシートにはりつければOKです。Googleスプレッドシートには「=image("画像のパス",引数)」で画像をシートにはりつけられる便利な関数があるので、それを使います。ソースだと

```javascript
  aSheet.getRange(i, 4).setValue('=Image("' + imagename + '",2)');
```

　の部分ですね。第2引数の2は、セルのサイズにサムネを合わせるようにするやつです。こうしてサムネ画像の列ができた後で、元の表に導入したのが以下のようなもの。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/288125/ba74cbb5-9eb8-9623-0571-d2420dee60ba.png)

　BOOTH以外のやつどうするんだとか色々ありましたけど、とりあえずこれでまたしばらくは戦えそうです。

#最後に

　リストですが、漏れが多いです。モデルの販売が多いというのもありますが、私一人では限界があります。誰でも編集可能にしているので協力プリーズ！　**URLを入れてくれるだけでいいから！**　後はいい感じに処理する仕組みを考えるから！