たまには技術寄りのネタで、
今日はGoogleスプレッドシートで自分のブログをスクレイピングしてみる。
という事で、書いていきます。
スクレイピングとは
スクレイピングとは、簡単に言うと、Webページの要素を分解して欲しい部分だけ(記事の一部やタイトルだけ等)を自動的に取り出す技術の事です。
Webページの一部の特定の情報を集めて集計をしたり、別のコンテンツに利用したい時などに使われます。
一見集計しにくい形になっていても、パターンを見つけ出してそれをプログラム等に落とし込んでいく事で高速に大量のデータを処理できるようになります。
scrapingという言葉の意味だけで言うと、「こそげ取る」といったような意味です。
ちなみに ↓こういう道具をスクレイパーと言いますね。
スクレイピングでやりたい事
自分の場合は自分のブログのタイトルだけをまず抜き出してリストを作り、そこから食費や摂取カロリーを集計するという事をやっていこうと考えています。
Googleスプレッドシートの機能を試していく
Googleスプレッドシートでスクレイピングをやった事は自分は無いのですが、なんとなくスクリプトが書けるという事は知っていたので、できるんじゃね?と思って調べながら記事を書いています。途中で行き詰らないといいな。
ブログのタイトルを取り出す。IMPORTXML()関数。
Googleスプレッドシートには便利な関数があるようで、IMPORTXML()という関数を使う事で、指定したURLの、特定の要素を抜き出してセルに表示してくれるのだとか。
やってみた。
- A1セルにブログのURLを入力
- A2セルにIMPORTXML()関数を入力。
↓このような感じ。
IMPORTXML()は第1引数に対象ページのURLを、第2引数にXPathという書式で取り出したいHTML内の要素を指定します。
XPathというのはHTMLの一部を指定する為の書式の事ですね。タイトルを取り出すのであれば「//title」となります。
ブログ記事のタイトルのリストを取り出す
1つの記事のタイトルを取り出すやり方は分かりましたが、やりたいのは「タイトルのリスト」を取り出す事でした。
まずタイトルを取り出したいブログ記事を絞り込みます。自分の場合は「節約ダイエット日記」のタグをつけた物だけを取り出したいので、タグで絞り込んだ結果ののページのURLを取得します。
↓このページのURLをA1セルに入力しておきます。
節約ダイエット日記 カテゴリーの記事一覧 - さんごーの節約&ダイエット日記。
そしてA2セルにIMPORTXML関数を使って以下のようにXpathを指定します。
=IMPORTXML(A1,"//div[@class='archive-entry-header']")
うまい具合に記事の投稿日とタイトルを取得する事ができました。
「class='archive-entry-header'」というのがはてなブログの記事一覧のページで使われているHTMLのdivタグのclass属性を指しています。
Googleスプレッドシート便利ですね。プログラマの仕事がどんどん無くなるね。
XPathの簡単な取得方法
XPathの取得はGoogleChromeを使うと簡単です。
タイトルのリンクを右クリック→コンテキストメニューから「検証」をクリック。
表示されたHTMLの要素のところで更に右クリック→Copy→Copy XPathを選択。
これでクリップボードにXPATHがコピーされます。
しかしXPathを取得する場所はどこでも良いわけではなく、XPathのパターンによってはIMPORTXML()がエラーになってしまいます。
この辺りはある程度自分で解決できないと使いこなすのは難しそうですね。
ブログ記事のタイトルを分割して食費、カロリー、体重だけ取り出す
正規表現というものを使って食費などの必要な部分だけ抜き出していきます。
正規表現というのは簡単にいうと、文字列のパターンを抽出して、一つの文字列で表現する事。です。
分からない人には全く分からないと思うので、興味ある方だけ調べてみて下さい。
説明の前に、実際にGoogleスプレッドシートでやってみた結果を示します。
C2以降のセルに
「=REGEXEXTRACT(B2, "節約ダイエット日記.+(\d{4}/\d{2}/\d{2}).+食費(\d+)円、摂取カロリー(\d+).+、体重(\d+)")」
といったような式を入力します。
日付、食費、摂取カロリー、体重の値がD列以降に書き出されている事が分かります。
上手くいきました!
REGEXEXTRACT()という関数を使ってブログ記事のタイトルを分割しています。
「.+(\d{4}/\d{2}/\d{2})」みたいな部分が正規表現の書き方になっています。
実際にはタイトルの表記ゆれを吸収する為に、もうちょっと複雑な正規表現になります。
スクレイピングした結果は文字列で出力されてしまうので、いったん数値に変換しないとグラフには使えないようです。
正規表現の超ざっくり説明
では、どういう事をしたのか簡単に解説していきます。
まず私の最近の節約ダイエット日記のタイトルは以下のようなものがあります。
- 節約ダイエット日記。あけましておめでとう。2016/12/31の食費3640円、摂取カロリー2213Kcal、体重63.5Kg。
- 節約ダイエット日記。仕事納め。もうちょっと休めば良かった。2016/12/30の食費1313円、摂取カロリー1771Kcal、体重63Kg。
- 節約ダイエット日記。体重計選びの続き。2016/12/29の食費349円、摂取カロリー2217Kcal、体重63Kg。
- 節約ダイエット日記。新しい体組成計を選び始めた。2016/12/28の食費988円、摂取カロリー2248Kcal、体重62.5Kg。
これらには見て分かるように、タイトルに共通のパターンがありますね。(そうなるようにタイトルを付けてるのですが)
パターンを書き出してみます。
- タイトルの先頭が「節約ダイエット日記」になっている。
- 日付が入っている
- タイトルの最後が食費○○円、摂取カロリー○○Kcal、体重○○Kgという形になっている。
これを「正規表現」のルールに乗っ取って書くと以下のような一つの文字列にすることが出来ます。
「節約ダイエット日記.+\d{4}/\d{2}/\d{2}.+食費\d+円、摂取カロリー\d+.+、体重\d+」
勘の良い方はこれを見て「あ~そういう事か~」となるのではないかと思います。
例えばこの正規表現文字列中の「\d」は数字を意味し、「\d{4}」とする事で「数字が4回続く」という意味になります。
つまり「\d{4}」で日付のうちの「2016」年の部分を表しています。
こんな調子で文字のルールを組み合わせていきます。
更に別のセルに出力したい部分を丸カッコでくくる事で、自動的にパターンにマッチした部分が書き出されていきます。
次にやりたい事
- 次はスクレイピングした結果を元にグラフを作成する。
- 月ごとに累計の食費を出力できるようにする。
- スクレイピング対象のページが複数に分かれた場合にも対応する。
意外とめんどくさそうなので、これらは次に回します。
とりあえずは試せたので満足です。
今回は以上です。
またよろしくお願いいたします。