GAS(Google Apps Script)でWebサイトをスクレイピングする方法の説明です。
matchメソッドで正規表現を駆使してもスクレイピングをできなくはないですが、Parserライブラリを使った方が100倍簡単です。
GASでスクレイピングすれば、毎日何時にとか何時間毎にといったようにWebサイトから定期的に情報収集することができます。
GASライブラリとは
簡単にいってしまえば、他の人が作った関数を利用できる機能がライブラリです。面倒臭い作業も賢い人が作ったライブラリを使えば自分でプログラミングする必要はなくなります。
Parserライブラリを導入する
Parserは、スクレイピングをするときにとても便利なライブラリで、下記で公開されています。
ライブラリを使用するときには、スクリプトIDが必要となりますので、
の部分をコピーしてください。
ライブラリの追加方法
スクリプトエディタを開いてライブラリの「+」をクリックします。
ライブラリ追加画面となりますので、スクリプトIDをペーストして、検索をクリックして追加すればParserライブラリが利用可能となります。
- ParserのスクリプトIDを入力
- 検索をクリック
- 追加をクリック
HTMLデータを取得する
毎日データが変わる 12星座運勢ランキング - Yahoo!占い を使って説明していきます。
先ずは、HTMLデータを取り込みます。
HTMLを取り込むときの注意点は文字コードとして何が使われているかです。文字コードを指定しないと文字化けしてしまいます。
Yahoo!占いで使われている文字コードは "euc-jp” です。<head>から</head>に charsetの記載がありますので探してみてください。
ちなみに、このブログである「象と散歩」の文字コードは "UTF-8” です。
GASでHTMLデータを取得するには UrlFetchAppクラスを使いますが、文字コードはgetContentTextで指定します。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')Logger.log(html)}
これでhtmlに格納されたHTMLデータが出力されます。
Parserライブラリの使い方
Parserの書き方は簡単で、抽出したいデータの中にある開始文字列と終了文字列に挟まれている文字列を抽出できます。
開始と終了に指定する文字列はhtmlタグである必要はありません。
また最後のbuild()関数は、最初に見つけたひとつだけを抽出する場合で、複数のデータを抽出するのであれば、iterate()を使います。
Yahoo!占いのタイトルと更新日を抽出する
では、早速 Yahoo!占い 12星座運勢ランキングからタイトルと更新日を取得してみます。「12星座運勢ランキング」というのは他のところからも取得できますが、画像で指定されているところから抽出してみます。
HTMLソースでは下記の部分となります。
「12星座運勢ランキング」を取得するために、直前の文字列 alt=" と直後の文字列 "> を指定します。
更新日には、開始と終了に <p class="txt"> と </p>を指定します。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')var title = Parser.data(html).from('alt="').to('">').build()var lastUpdated = Parser.data(html).from('<p class="txt">').to('</p>').build()Logger.log('タイトル= ' + title)Logger.log('更新日 = ' + lastUpdated)}
実行結果をみるとタイトルが正しく抽出されていません。
前述したように build() は、最初に見つけたものとなるので、
が、先にマッチしてこの部分が抽出されたようです。
もう少し、開始文字列を多くして、他で一致しないようにします。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')var title = Parser.data(html).from('txt08.gif" alt="').to('">').build()var lastUpdated = Parser.data(html).from('<p class="txt">').to('</p>').build()Logger.log('タイトル= ' + title)Logger.log('更新日 = ' + lastUpdated)}
今度は正しく取得できています。
複数の値を取得する
Yahoo!12星座運勢ランキングのソースをみると、1位から12位まで表形式(tableタグ)で組み立てられています。
1行毎に薄い色と濃い色とで変えているので、簡単に記載するとこんな形です。
<tr class="st01">で始まっているのが奇数の順位のもので、<tr class="st02">が偶数順位ですが、iterate()を使うと一気に配列として取得できます。
list_odd[5]でランク11位、list_even[5]でランク12位の情報が取得できます。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')//奇数順位の星座var list_odd = Parser.data(html).from('<tr class="st01">').to('</tr>').iterate()//偶数順位の星座var list_even = Parser.data(html).from('<tr class="st02">').to('</tr>').iterate()Logger.log(list_odd[5])Logger.log(list_even[5])}
Parserを複数回利用して値を取得する
Parserを繰り返し使用することで目的の値を簡単に取得することができます。
上で取得した各星座のデータからランク、星座名、コメントを取得します。
スクレイピングのプログラミングのコツは、共通点を見つけるということです。共通のロジックでデータが取得できるかという観点でHTMLデータを俯瞰的に見てください。
順位の取得
詳細項目の取得方法について順位を使って説明します。
<td class="st01"> ... </td> の中にランキング情報があり、alt=" ... "> 中に順位がありますので、Paserを2回使って順位を取得します。以下がGASのコードとなります。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')//奇数順位の星座var list_odd = Parser.data(html).from('<tr class="st01">').to('</tr>').iterate()//ランクを取得var rank = Parser.data(contents).from('<td class="st01">').to('</td>').build()rank = Parser.data(rank).from('alt="').to('">').build()Logger.log(rank)}
上記で「1位」と表示されます。
順位、星座名、コメントを取得する
下記が、Yahoo! 12星座運勢ランキングから、順位、星座名、コメントを取得するGASのコードとなりますので参考にしてみてください。
function myFunction() {var url = "https://fortune.yahoo.co.jp/12astro/ranking.html" // Yahoo!占いvar html = UrlFetchApp.fetch(url).getContentText('euc-jp')//奇数順位の星座var list_odd = Parser.data(html).from('<tr class="st01">').to('</tr>').iterate()//偶数順位の星座var list_even = Parser.data(html).from('<tr class="st02">').to('</tr>').iterate()for(var i=0; i<list_odd.length; i++) {//奇数順位の星座results_odd = parse(list_odd[i])Logger.log(results_odd)//偶数順位の星座results_even = parse(list_even[i])Logger.log(results_even)}}function parse(contents) {//ランクを取得var rank = Parser.data(contents).from('<td class="st01">').to('</td>').build()rank = Parser.data(rank).from('alt="').to('">').build()//星座名を取得var seiza = Parser.data(contents).from('<p class="seiza">').to('</p>').build()seiza = Parser.data(seiza).from('alt="').to('">').build()//コメントを取得var text = Parser.data(contents).from('<p class="ft01">').to('</p>').build()text = Parser.data(text).from('">').to('</a>').build();var results =[rank, seiza, text]return results
}
GASの基礎を学べる参考図書
ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。
「詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。
Udemy オススメ講座
【新IDE対応】Google Apps Script(GAS)の基礎を完全習得
講師:事務職たらこ
印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。