Javaではてなブックマークのスクレイピングに挑戦しよう(ネット上の大規模データ取得編)

こんにちは、らくからちゃです。

以前から何回かに分けてお伝えしてきた『Javaはてなブックマークのデータ解析入門』シリーズですが、お陰さまで沢山の人に読んでもらえて頂いたようで、書き手冥利に尽きます。

さて、過去3回にわけて、初歩的なところから書き綴ってきましたが、そろそろ本題に入りましょう。このシリーズの本来の目的は『ネット上から大規模データを取得して解析する』ということです。ずいぶん長くはなりましたが、今回で前半の『ネット上の大規模データの取得』について一段落つけてみたいと思います。

近年、こういった大規模なデータを『ビッグデータ』なんて呼ぶこともあり、みなさまも耳にしたことがあるかもしれません。

今回からは、かなり大規模なデータを対象とすることになります。今回は、今まで行ってきた下記3つのノウハウを全て組み合わせて使います。

  1. ブックマークデータの収集編)
  2. 対象データのスクレイピング編
  3. sqliteへの格納編

1では、json形式のデータの利用について。2では、jsoupを利用したスクレイピングについて。3では、sqliteの利用方法について確認してきました。本稿は、前記の3記事を既に読了済みの前提で記載させて頂きます。

それじゃあ、

いっくぞー( ・`д・´)

ライブラリの取得と下ごしらえ

 今回もまた利用するライブラリが増えます。いつもどおり追加をお願いします。

先に解説しておくと、『XML RPC』という形式でデータ通信を行うために必要なライブラリセットです。はてなブックマークのブログ別総数を取得するために必要なものです。(素直にjsonにすればいいのに・・・)

f:id:lacucaracha:20160220185414p:plain

お次に引数です。ちょっとわかりにくいのですが、

f:id:lacucaracha:20160220185421p:plain

  1. 任意のユーザー名(誰でも良い)
  2. 実行回数(とりあえず10くらいでも良い)
  3. dbファイルへのパス

の順番に、空白スペースを開けて指定して下さい。 

lacucaracha 100 /Users/hoge/HatenaBookmark.db

みたいな感じですね!

ソースコードの貼り付けと実行

さてここまでくれば、いつもどおりソースコードをコピペでOKです。

まずは、こちらのSQL文をSQLStudio等から実行し、テーブルを追加して下さい。(一度データベースファイルを開かないとだめですよーん)

gist4b18350203c078aeac07

お次はJavaです。これも以前使ったファイルと差し替えて下さい。このファイルを実行すると、小一時間ほどかけてデータをDB上にストックいたします。なお、プログラムを再実行すると、一度取得したデータを消してから作り直す動きになりますのでご注意くださいね♪

gistfd0e7d857d6041ed53c4

ずいぶん長くなりましたね(^_^;)。さて、出力結果をご説明する前に、プログラムの動作概要からご説明しましょう。

プログラム動作概要

今回のプログラムは、『はてなブログの読者登録の関係から、人気のあるブログのデータを収集する』という観点で組まれています。具体的な動作概要としては下記のとおりです。

f:id:lacucaracha:20160220190617p:plain

まず最初に指定したブログの読者IDを取得します。次に、読者IDで運用されているブログの『はてブ総数』を取得します。また、指定したブログの『読者数』『feedly登録数』『直近100記事に対するブックマーク』を取得します。

ここまでがプログラムの『一周』です。そして取得した読者一覧から、『はてブ数が多く、まだデータを取得していないブログ』を取得し、一連の処理を再帰的に実行します。これを、引数で指定した回数だけ実行するわけですね。

続いて、プログラムの実装ポイントをご説明したいと思います。

特定ブログの読者を取得する

まず指定のブログの読者数を取得する方法です。はてなブログでは、ブログURL+/aboutから、ブログを読者登録している人の一覧を取得することが可能です。『ゆとりずむ』の場合こんな感じ。

昔、全員分表示されていたのですが、ここ最近行われた仕様変更で100人分がランダムに表示されるようになりました・・・。はてなはん、なんでや!なんで全員分出してくれへんねん!ヽ(`Д´)ノ

とまあ怒りをぶつける前に、このページの構造を解析してみましょう。HTMLコードを見てみると、こんな感じになっています。

f:id:lacucaracha:20160220191414p:plain

<span class = "about-subscription-count">◯◯人</span>で読者数が管理されています。また、読者のIDがimgタグのtitle要素に付けられていますね。これを片っ端からソースコードのこの部分です。

f:id:lacucaracha:20160220191805p:plain

 さて、次に読者の個別情報を取得してみましょう。上の画像で言うと、その処理を行っているのが"getHatenaIdData"になります。

読者のブログ情報を取得する

まず、はてなのIDブログの情報を取得したいのですが、どうすればよいでしょうか?独自URLなど、ID名とブログ名が一致しない人も多いですよね。でもご安心を。IDさえわかれば、http://blog.hatena.ne.jp/ + ユーザID でアクセスできます。

ただし、IDと紐づくのはメインブログだけです。よって、今回の集計対象からサブブログは入りません。あとは、ページ冒頭のHTMLタグ内にこんなデータがあるのでこれを利用します。

f:id:lacucaracha:20160220192807p:plain

これで、ブログの正式なURLとタイトルも分かるわけですな〜。

読者のブログのはてブ総数を取得する

次に取得したブログの『はてブ総数』を取得しておきます。取得したブログから、次に調査する対象を選択するにあたって、ランダムに選ぶのではなく、『ブックマーク数の多いブログ』を選ぶことによって、人気のブログを取りこぼしなく調べることができます。これは、『次に見に行くブログ』を探すために必要な処理です。

その処理がこの部分になります。

f:id:lacucaracha:20160220193150p:plain

詳しい動作仕様はこのへんに記載がありますが、特定の『サイト』の過去に取得したブックマーク総数を取得する処理です。

Javaでやるから色々と面倒くさいですよね(^_^;)でもま、これでひとまずはてブ総数もつかめたので良しとしましょう。

読者数・feedly登録者数の取得

ここまでは、『読者』に対して行ってきましたが、次に『調査ブログ』のデータもとっておきましょう。

まず、読者数。先程も記載しましたが spanタグのabout-subscription-countというところに◯◯人の形で記載されています。なお、極稀ではありますが英語モードにしている場合◯◯peopleになるようです。なのでこれを、適当に空白に置き換え、ただの数字にします。

そしてfeedlyの件数。 http://cloud.feedly.com/v3/search/feeds?query= URLでJSON形式で対応すると思われるデータがあれば返します。ゆとりずむの場合、こんな感じですね。

JSONなのでちゃんと変換しても良いのですが、なんか面倒くさくなっちゃって適当に文字列を置換して処理してます(ノ∀`)アチャー

あとブックマークデータについては、過去の記事記載の通りです。詳細については割愛致しますが、これらの処理を行っている箇所がここ。

f:id:lacucaracha:20160220194058p:plain

次の調査対象を取得

最後の処理として、次の調査対象を取得します。取得のルールは、『読者登録数が0=まだ調査していない』かつ『はてブ総数が多い』です。格納されているデータから、SQL文を投げて、対象データを取得します。

f:id:lacucaracha:20160220194331p:plain

(画像がちょっと途切れているけどごめんね)

テーブルの構造

今回、調査した結果は下記のテーブルに書きだされます。ざっくりまとめると

  • Pages ・・・ 記事に対するブックマークの概要
  • Bookmarks ・・・ 個別のブックマーク
  • Hatena_ID ・・・ 個別のユーザ
  • Blog_Subscriber_ID ・・・ ブログの購読状況

について格納しています。細かい内容は、カラム名から察して頂くか、プログラムのコードを見て下さい(という弊社の開発にありがちな投槍解説)

f:id:lacucaracha:20160220195810p:plain

出力結果

このプログラムを最大100ブログを対象としてぐるぐる実行した所、以下のデータが取得できました。

  1. 調査対象記事数 ・・・ 6,042件
  2. 調査対象ブックマーク数 ・・・ 29万7,924件
  3. 調査対象ブログ数・・・ 3,962件(うち詳細情報取得100件)

データの規模としては、まあまあ面白いことができそうな感じではないでしょうか!?せっかくなので、出力データの結果を一部出してみましょう。まずはド定番の読者数ランキングから。

タイトルfeedlyはてブ総数読者登録
Everything you've ever Dreamed 5225 66327 3266
ICHIROYAのブログ 1351 36244 2038
トイアンナのぐだぐだ 1145 10929 1989
ぐるりみち。 943 26615 1815
ゆとりずむ 1138 35360 1674
はなこのブログ。 897 9554 1571
今日はヒトデ祭りだぞ! 729 20494 1478
コスパ最強!!一人暮らしの簡単節約料理レシピ 1008 19130 1401
しっきーのブログ 837 21622 1383
さっきもUたやん 757 12046 1379

 あれー?あの人とかあの人がいないよーという人もいるかもしれませんが、これは調査アルゴリズムに依存するものです。『読者登録した人の中から次の調査対象を探索する以上』どのブログも読者登録していない人は調査対象から外れます

また今回のはてなブログの仕様改変のため、読者一覧に表示されるかどうかはランダムになりました。そのため、いろんなブログに読者登録している割合が多いほうが上位にきやすい性質を持っています。

次に、『ブックマーク数の多かった記事ベスト30』。これは調査対象となった100ブログに付けられた記事の中で、直近100記事から取得してきています

タイトルカテゴリ件数
【無料】最強のオンライン英会話学習サイトVerblingをなぜ誰もオススメしないのか 学び 2722
「仕事の遅い人」が読むだけで絶対に仕事が早くなる方法 - さようなら、憂鬱な木曜日 暮らし 2121
ある程度パソコンが使える人が「Excelが使いこなせるようになりたいぞー」と思ったときに独学できるサイト4個。 - おしい県でWebに携わって働く人のブログ テクノロジー 2093
簿記の基礎と基本について10分くらいで分かるようにまとめてみる - ゆとりずむ 政治と経済 1847
身内が死んだら注意すべき葬儀周辺での悪意について - 空気を読まない中杜カズサ 暮らし 1816
「明日から本気出す」という人にオススメの日本語で学べるプログラミング学習サイト9選 - おしい県でWebに携わって働く人のブログ テクノロジー 1737
他人が作った「企画書」や「提案書」や「プレゼン資料」を堂々と覗き見することができるサイトやブログ記事まとめ。 - おしい県でWebに携わって働く人のブログ テクノロジー 1681
【永久保存】人生を最高に楽しくするTEDおすすめ10選 - コスパ最強!!一人暮らしの簡単節約料理レシピ 学び 1577
ご飯2合ぐらいならすぐに食べてしまう美味しさ「ネギ塩チキンライス」 - オレシピ - 俺のレシピはお前のレシピ- 暮らし 1552
年150万は食費に突っ込む女が本気で薦める、20代で通いたいお店 - 外資系OLのぐだぐだ 暮らし 1552
「わかりやすい説明をする人」と評価されるプレゼン術。作り方と話し方。 - 僭越ながら【1テーマの本を30冊読んで勉強するブログ】 暮らし 1454
エクセルVBAを学びたいので、良さそうなサイトをまとめた - 株式、FXのまとめ解説 テクノロジー 1388
「察してほしい」気持ちをなくせば夫婦喧嘩は8割減る - はなこのブログ。 暮らし 1338
一人で意味もなくビジネスホテルに泊まるのが好きだ - phaの日記 暮らし 1269
コミュニケーション能力の高い人の話し方の共通点 - ゆとりずむ 暮らし 1264
もっと早く知りたかった・・・虫歯予防、歯磨き方法のまとめ - 株式、FXのまとめ解説 暮らし 1238
英語で「宜しくお願いします」をどう書けば?"ニュアンス語"を簡単に伝える英文メールの書き方 - 外資系OLのぐだぐだ 暮らし 1222
英語初心者がたった3ヶ月でTOEICで800点取る方法 - コスパ最強!!一人暮らしの簡単節約料理レシピ 学び 1221
勉強ができる人とできない人の、ノートの取り方における決定的な違いについて - さようなら、憂鬱な木曜日 暮らし 1214
海外生活で感じた初心者が旅行に持って行くべきモノ 20選 - My Favorite 暮らし 1204
将棋の初心者がたった10ヶ月でアマチュア1級を取る方法 - コスパ最強!!一人暮らしの簡単節約料理レシピ アニメとゲーム 1144
LCC格安航空券セール情報を見逃さないための3サイト 政治と経済 1132
株主優待で悠々自適の生活を!5万円以下で購入可能な株主優待銘柄93選一挙公開 - サラリーマン休日副業で月10万円以上目指すページ 政治と経済 1073
勉強で最も重要な「反復訓練」の手順。これ無しに熟練者になることはあり得ない。 - 僭越ながら 暮らし 1049
「考えが浅い」「発想が平凡」なのは、"考えるステップ"を実践していないから - 僭越ながら 学び 1031
株式投資を始める人向けの記事まとめ(自薦) - 株式、FXのまとめ解説ブログ 政治と経済 1003
WEB界隈で働く人が重宝しそうな「WEBマーケティング」と「SEO」のチートシート6+2個まとめ。 - おしい県でWebに携わって働く人のブログ テクノロジー 984
女ウケがバツグンに良い"香り"を教えてやるよ - My Favorite 暮らし 979
1/2個ぐらいならペロリと食べられる。白菜大量消費におすすめ「白菜のナムル」 - オレシピ - 俺のレシピはお前のレシピ- 暮らし 971
集中力と記憶の定着率が高まり、体系的な知識が身に付くアウトプット勉強法 - 僭越ながら 学び 965

 全体的にノウハウ系が多い感じですかね〜。意外と無視できないのが『料理系』の需要の強さ。こうやってみてみると色々なことがわかりますね!

あとですね、これは声を大にして言いたいのですが、

データの分析をするときは、そのデータがどのように作られたものかを意識しましょう

今回の例だと、

  • 誰のブログも読者登録をしていない人は表示されない
  • 直近100記事に対するブクマを対象としている

などなど、データの示せる情報には一定の『限界』があります。それを知るには、一度自分でデータを作ってみるのもいいと思いますよ♪他にも、色々なデータがあって、様々な分析が出来るのですが、その辺は次回以降に回しましょう。

ではでは、今日はこの辺で。