初心者がGASでウェブスクレイピングするSlackBotを作ったお話
・経緯
散々挫折したプログラミングにもう一度挑戦しようとProgateをやってみたり、色々記事を読んだりしていた。すると初心者はまずチャットボットを作ってみよう、GASがオススメだよ!という記事があり、友人はRubyとかでウェブスクレイピングしてみると色々分かっていいよ、と言う。
よくわからなくなったので全部やることにした。
・目標物
麹の温度を測るWeb温度計のデータをサイトから引っ張ってきて、google spreadsheetに記録、Slackに通知させるという物。業界標準(?)の温度計、Web麹守りの記録サイトhttp://www.oyasai.com/があまりに使いづらいため。
・完成物
コードべた張りしたら見栄え悪すぎたのでGithubに上げてみた。これまた使い方全くわからなくてビビった、とりあえず上がったのでよし(?)
・つまずいたところ,POSTとGET
上記を参考にGASの使い方を軽くかじったあと、よっしゃSlackで試すぞと、
これの通りにコードを書いた(ペーストした)ところ、投稿はできるけどOutgoing webhookのリクエストに反応しなかった。色々いじったり読んだりした結果、サンプルはdoGet(e)だが他のサイトはdoPost(e)と書いていたりして、Outgoing webhookはPOSTリクエストだというのが分かった。当然GETとPOSTが何なのかここで初めて学んだ。また、
なおコードの更新後、GASプロジェクトのバージョンを上げ、ウェブアプリケーションのバージョンを上げるのを忘れないで下さい。
何言っているかわからない人は多分「コード更新したんだけど動かない」ってなるはずです。
その時上の呪文を唱えて下さい。
というのも意味がわかっていなかった。ちゃんとバージョンを上げたりGET,POSTと格闘している内にちゃんとOutgoing webhookに反応するようになった。どっちが核心だったのかはわからん。
・つまづいたところ,サイトのログイン処理
この辺を参考にコードペタペタしたところ、全然ログインが通らない。
うーんどうにもわからん何をPOSTすればいいのか、中身見れんのかと四苦八苦していると、
上記のサイトを見つけて、そのとおりにやってみた。するとoyasaiが要求しているpayloadはlogin_idとpasswordだけでなくlogin:"ログイン"というsubmitボタンの値(?)も要求していることがわかった。のでそれを添えてあげたら無事にログインができた。
・つまづいたところ,データの抽出
上記サイトを参考にスクレイピングをしようとしたところ、XmlService.parse()でエラーがでて先へ進めない。調べてみると、どうもエラーが出やすいものらしく、正規表現で抽出している記事がいっぱい出てくる。当然正規表現なんて全くわからず、HTMLもこんなありさまなので
<tr>
<td><input type="text" style="width:25px;" name="view_update_id[1231]" value="1"></td>
<td>
<input name="g_del_id[1231][3992]" type="checkbox" value="1">
</td>
<td><a href="/common/graph_view.php?graph_id=MTIzYjdmMDI0MzM1NzJhMGE1NjBlNjIwMzExYTQ2OWM&x_view=24&y=2018&m=09&d=29&h=14&i=15" target="_blank">テスト1</a></td>
<td></td>
<td></td>
<td>品温</td>
<td>
31.50
</td>
<td>℃</td>
<td>2018/09/29 14:39</td>
</tr>
全く抜き出せる気がしない。唸りに唸ったところで、
Xml.parse で解析したデータに、XmlService.parse して解析すると良さそうとのこと。
Xml.parse で有効なXML形式に変えてくれるんですね。
//xmlをパースするよくわからんやつ
var doc = Xml.parse(content,true);
var bodyHtml = doc.html.body.toXmlString();
doc = XmlService.parse(bodyHtml);
var root = doc.getRootElement();
//品音を取得
var td = parser.getElementsByTagName(root, "td")
//7,16,25,34
var data = [[td[7].getValue(),td[16].getValue(),td[25].getValue(),td[34].getValue(),td[9].getValue()]];
よくわからんけどまんま真似して書いたら通った。よくわからんけどライブラリを用いてタグ指定したら品温を取り出せたので、2次元配列にまとめてスプレッドシートに書き込めるようにした。
・終わり!閉廷!…以上!皆解散!
あとはSlackから送られてくるトリガーワードで条件分岐して始めにシートを新しく作ったり、毎5分動作のイベントトリガーを設置させて終わりに削除させてたり、Slackに送るメッセージの整形をしたりした。
無事に動くものができた~~~~!!!やった~~~~!!!
・感想
いざ作ると決めてから丸一日半もかかってしまったが、初めてちゃんと動くものを作れたのでとても嬉しい。GASでウェブスクレイピングはするものじゃない気がするけど、全くの初心者でも動くウェブアプリ(?)を作ることができたので、入門には良さそう?とにかく完走できてよかった。
以上!!!!!