ゆとりずむ

東京で働く意識低い系ITコンサル(見習)。金融、時事、節約、会計等々のネタを呟きます。

どこにも遊びに行けないなら"はてブ"のデータ分析をして遊べばいいじゃない

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

2年連続ステイホームのゴールデンウィークになりそうです。

もはやゴールデンウィークって普段何してたのか忘れかけてきたので、過去の履歴を漁ってみたら、一昨年は伊豆半島の東側をぐるぐる回りながら下田までいってたみたいです。

こんなどこにも行けない日には、家でデータ分析をするに限りますね!!(鼻息)

統計局が、e-statを使って遊ぶ方法も教えてくれるそうなので、ご興味がある方は是非!

gacco.org

統計として公開されているデータを眺めてみるのも面白いっちゃ面白いのですが、データ分析の醍醐味は統計処理される前の生々しいデータを弄くり倒すところにあると思うんすよ。

ただKaggleでランカー目指すぞい!!と殴り込みに行くにはハードルが高いなあとお思いでしたら、目の前になかなかいじり甲斐のありそうなデータがあるじゃあないですか。コイツです。

f:id:lacucaracha:20210503120304p:plain

はてブデータ収集ツールの使い方 

定期的に「はてなスターランキング」と称した記事を書いておりますが、このランキングは、はてなの公開しているAPIを叩いて出てきたデータを使用しています。 

www.yutorism.jp

これらのデータは、数年前にたまたまそのとき勉強していたJavaで書いた自家製ツールで収集していました。ただメンテ性も良くないし、いろいろと直しておきたい箇所もあったので昨年末にPythonで書き直してみました。

かなり扱い易くなったはずですし、個人的な備忘も兼ねて、データ収集の方法について整理したいと思います。

ツールの開発・実行環境は、

  1. iMac 27-inch,Late 2013(そろそろ買い替えたい)
  2. mac OS Catalina 10.15.7
  3. Python 3.7.1 (Catalinaの標準)
  4. SQLiteStudio 3.3.3

になります。特に有償のツールやサービスは使いません。同じような環境であれば、WindowsでもLinuxでも平気なはず。あとはネットと電気とやる気があれば大丈夫(たぶん)

データの収集・集計には、SQLを使用しますが、特に難しく考えなくて平気です。(むしろちょうどよいSQLの練習になるかも)

1〜3まではMacなら勝手についてきているはずです。Windows・Linuxの似たようなバージョンを突っ込んでください。4のSQLiteStudioは下記から別途インストールしておきましょう。

インストールできたら、データを保存するデータベースファイルを作りましょう。

f:id:lacucaracha:20210504102907p:plain

分かりやすくドキュメント直下にファイルを作ってみます。(別の場所でもOKですが、デスクトップみたいに権限が付与できない場所だとアレかも)

f:id:lacucaracha:20210503133421p:plain

作ったファイルの中に

  1. Page(対象となるページの情報)
  2. Bookmark(個別のブックマーク情報)
  3. Star(ブックマークに対するスター)

の3種類のデータを格納するテーブル(表)を作成します。以下の呪文を順番に詠唱すればOKです。(②→③をそれぞれ3回実行)

Page

CREATE TABLE Page (
    EID       VARCHAR (4000) PRIMARY KEY,
    DATE      DATE,
    CATEGORY  VARCHAR (4000),
    ENTRYRANK NUMERIC (5),
    COUNT     NUMERIC (5),
    TITLE     VARCHAR (4000),
    URL       VARCHAR (4000) 
);

 Bookmark

CREATE TABLE Bookmark (
    EID          VARCHAR (4000),
    BOOKMARKUSER VARCHAR (4000),
    URL          VARCHAR (4000),
    STARCOUNT    NUMERIC (5),
    TIMESTAMP    DATETIME,
    COMMENT      TEXT,
    TAG          TEXT,
    PRIMARY KEY (
        EID,
        BOOKMARKUSER
    )
);

Star

CREATE TABLE Star (
    STARUSER     VARCHAR (4000),
    COLOR        VARCHAR (4000),
    BOOKMARKUSER VARCHAR (4000),
    EID          VARCHAR (4000),
    QUOTE        TEXT
);

作ったテーブル構造の説明もしておきたいところですが、データが入った段階じゃないとイメージがつきづらいでしょう。細かい解説は後回しにして、まずデータを取得しましょう。

さてここで、今回Python化した収集スクリプトの登場です。

Hatena

非エンジニアが「動けば良い」の崇高な精神のもと書いたスクリプトなので、ツッコミどころは満載だと思いますが、気にせず適当な名前で保存してください。そうですね "hatena.py" にでもしましょうか。

このスクリプトは、標準のライブラリに加えてBeautifulSoupを使います。ターミナルを起動し、以下のコマンドでインストールしましょう

pip install beatifulsoup4

これで準備完了です!! 

このスクリプトは、

  • 第一引数 取得対象の年月日(YYYYMMDD)
  • 第二引数 格納先のデータベース

で実行できます。ターミナルで下記のように命令を実行ください。

python /Users/xxx/Documents/hatena.py 20210101 /Users/xxx/Documents/Hatena.db

こんな感じで、データの取得が始まれば成功です。

f:id:lacucaracha:20210504104148p:plain

はてブデータ収集ツールの仕組み

このツールがどんな手順でデータを取得しているのかは、中のデータの特性を抑えるためにも必要だと思うので、簡単に説明いたします。はてなブックマークには、デイリーのランキングページがあります。

例えば、2021年1月1日だとこんな感じ。末尾の部分が指定した引数と同じになります。 

https://b.hatena.ne.jp/hotentry/all/20210101

ページを開いてデベロッパーツールで眺めてみると、"entrylist-contents"の中に、それぞれの要素が格納されていることが見て取れます。

f:id:lacucaracha:20210504124829p:plain

この中から、記事のURLのリンク部分を取得して、はてな社が公開しているAPIに投げつけて、それぞれのページに対するブックマーク情報を取得します。全ブックマークデータを対象とすると処理に時間がかかりすぎるため、コメント付きブックマークに対してスターの付与状況を取得します。

APIの詳細は下記をご参照ください。

こうしてウェブページからデータをぶっこ抜いてくる手法を「スクレイピング」と言います。詳細は、さいとーさんの本が大変評判が良いので気になる人はご一読ください。

話を戻すと、このスクリプトでは

  1. デイリーランキングに乗っているページが対象
  2. 取得したページから、コメント付きのブックマークに対してスターを取得

になります。よって、

  • デイリーランキングに乗り切らなかったページへのコメント
  • タグだけ、コメントを後で消したコメントへのスター

は集計対象から外れますので、その前提で扱ってください。

はてブのデータを見てみよう

SQLiteStudioで、まずは単純に取得したページのデータを見てみましょう。以下の手順で操作してください。

f:id:lacucaracha:20210504130938p:plain

下記のようなデータが表示されました。

  1. EID
  2. DATE
  3. CATEGORY
  4. ENTRYRANK
  5. COUNT
  6. TITLE
  7. URL

列名でおおよそ推察がつくとおもいますが、この中で分かりづらいのは「EID」でしょうね。これは(おそらく)EntryIDの意味で、各ページに対してはてな側が付与している識別用IDです。

なおDATEはランキングに表示された日付(≠記事が投稿された日付)で、RANKは当日ランキング上の表示順です(≠ブクマ数順位)。

次に、特定ページに対するコメントをスター数の多い順番に並び替えて見ましょう。

f:id:lacucaracha:20210504132243p:plain

Bookmarkテーブルを開いて、フィルター窓に抽出したいEIDを指定して、Starcountを降順ソートすれば結果が見れます。これくらいの内容であれば特にSQL文を書く必要もありません。

もう少し複雑なデータを取得する場合は、SQL文を書く必要があります。例えば下記は、「lacucarachaのブックマークに対してスターをつけた人を、ページ毎の重複ブックマークを除いて集計し、降順で表示する」といった命令になります。

select 
 staruser,count(distinct EID)
from 
 Star
where 
 bookmarkuser = 'lacucaracha'
group by staruser
order by count(distinct EID) desc

 実際にこのSQLを実行するとこんな感じに表示されました。ほお・・・。

f:id:lacucaracha:20210504133641p:plain

SQL文が書ければ、かなり複雑なデータを抜き出すことも出来ますし、エクセルに結果を貼り付けることも出来ます。あとは解析してブログに書くもよし、増田に怪文書を作るもよし、機械学習の教師データとして使ってみても面白いでしょう。

取得したデータを個人の趣味の範囲で利用するぶんには問題ないと思いますが、念の為API規約についてもご一読ください。

developer.hatena.ne.jp

この程度でどうにかなる、はてなのサーバーではないと思いますが、「当社または他者のサーバーに過剰に負荷をかける機能」にならない範囲でお楽しみくださいまし。

ではでは、今日はこのへんで

今週のお題「おうち時間2021」