Web で面白そうな記事を見つけた場合、読むのに時間かかりそうなのは Pocket に保存しますが、すぐ読めそうなのはざっと読んで記事内の Tweet アイコンから Twitter に流すことが増えています。
昔は Twitter よりも Tumblr を好んで使っていたので記事内のハイライト的なパラグラフを選んで quote して Tumblr に放流してました。最近は quote の頻度は下がっており、たまに Dashboard を見に行ってポツポツと5, 6個 reblog して閉じるということが多いです*1。
Tumblr に quote を放流してると、たまに reblog されまくることがあります。フォロワーの多い人に reblog され、さらに quote over100notes jp などハブアカウントに捕捉されると数が伸びます。reblog にしろ quote にしろ、オリジナルの記事を書いたわけではないので twitter の retweet とは全然別物ですが、自分が放った quote に反応があるとそれはそれで嬉しかったりします。ただ、自分のアーカイブを遡っても、notes(reblog や like) の数はあまり把握できないため、過去にどんな投稿の notes が多かったか振り返ることは簡単にできません。
以前、ストック情報サイトを tumblr のセカンドブログとして構築した時に、Tumblr API をちょっと触ってました。
ドキュメントを眺めていると notes_count など反応数も取れそうなので、HTML + JavaScript の簡易な環境でデータ取得を試してみました。確認したのは、Chrome 63.0.3239.132 です。
あらかじめ以下で API Key を取得しておきます。
https://www.tumblr.com/oauth/apps
API の URL、対象の Blog の識別子(ドメイン)、API Key をリクエスト URL 構築用に宣言します。
baseurl = "http://api.tumblr.com/v2/blog/"; domain = "your.tumblr.identifer" api_key = "yourapikey";
投稿数を取得するには、info
メソッドを利用します。
https://api.tumblr.com/v2/blog/your.tumblr.identifer/info
Blog の識別子をパスパラメータ、API Key をクエリパラメータとして指定します。
response を JSON 形式で取得すると、キー 'blog'
で取得できるオブジェクトから以下のような情報が得られます。
フィールド | 説明 |
---|---|
title | Blog のタイトル |
posts | 投稿数 |
name | Blog の短縮名 |
updated | 最近の投稿日時 |
: | : |
'posts'
フィールドに Blog 投稿数が格納されています。
fetch API で投稿数を取得する例です。
async function getPostCount() { var count; await fetch(`${baseurl}${domain}/info?api_key=${api_key}`).then(response => response.json()).then(json => { count = json['response']['blog']['posts']; }); return parseInt(count); }
投稿に関する情報は、posts
メソッドを使用して取得します。
https://api.tumblr.com/v2/blog/your.tumblr.identifer/posts
パスパラメータに Blog 識別子と投稿タイプ (type
: text / photo / quote / link ..etc.) を指定します (投稿タイプは省略可能)。クエリパラメータとして API Key の他に reblog_info
と notes_info
という bool 値を指定する必要があります。一度に取得できる投稿情報は20件なので、取得開始位置を表すクエリパラメータ offset
を指定して繰り返し取得します。投稿は投稿日時の降順で取得できます。
クエリパラメータ | 説明 |
---|---|
reblog_info | reblog 情報を取得するか指定 |
notes_info | notes(reblog や like) 情報を取得するか指定 |
offset | 投稿の取得開始位置 |
reblog_info
を指定すると reblog 情報として、reblogged_root_name
が取れます。これが実はオリジナルの投稿者 (blog 短縮名)で、この値が取得できない場合、それは自分の投稿ということになります*2。notes_info
を指定すると投稿に対する反応 (reblog や like) 数 note_count
を取得できます。
投稿情報を取得する関数のコード例です。引数には type
(投稿タイプ:空文字だと全タイプを取得)、offset
、minCount
(反応数の閾値) を指定するようにしています。簡便のため取得したデータはその場で CSV としてレンダリングしてます。
function fetchPosts(type, offset, minCount = 0) { fetch(`${baseurl}${domain}/posts/${type}?notes_info=true&reblog_info=true&offset=${offset}&api_key=${api_key}`) .then(response => response.json()).then(json => { $("#offset").html(`offset:${offset}`); $.each(json['response']['posts'], function() { if (!this['reblogged_root_name'] && parseInt(this['note_count']) >= minCount) { $("#posts").append(`${idLink(this['id'])},${this['date']},${this['type']},${this['slug']},${this['note_count']}<br />`); } }); }); }
メインの処理では、投稿数取得のコールバックでループを回して全投稿分の処理を行います。1回の呼び出しごとに 500ms のスリープを入れています。
$(function() { getPostCount().then(count => { var offset = 0; while (offset <= count) { fetchPosts('', offset, 3); offset += 20; sleep(500); } }); })
僕は 2008 年頃から Tumblr を始めていて、2017年1月6日時点で投稿総数 6562 件でした(ほとんどがフォローしている人の投稿の reblog です)。測定してませんが全件分処理するのに体感で3分程度でした。
reblog じゃない自分が投稿した中で、3件以上反応があったものをタイプ別に集計すると以下のようになりました。
type | post |
---|---|
link | 7 |
photo | 36 |
quote | 126 |
text | 5 |
video | 4 |
やはり quote が母数も多いし、数が多かったです。上位結果は以下のようになりました。
quote:
post_url | date | note_count |
---|---|---|
http://reblog.kondoumh.com/post/116903557247 | 2015-04-20 | 2072 |
http://reblog.kondoumh.com/post/128707132367 | 2015-09-09 | 901 |
http://reblog.kondoumh.com/post/101674369492 | 2014-11-03 | 797 |
http://reblog.kondoumh.com/post/100990796202 | 2014-10-26 | 567 |
http://reblog.kondoumh.com/post/125576816117 | 2015-08-01 | 337 |
http://reblog.kondoumh.com/post/113365328582 | 2015-03-11 | 304 |
http://reblog.kondoumh.com/post/92392064267 | 2014-07-21 | 224 |
http://reblog.kondoumh.com/post/78287627384 | 2014-03-02 | 209 |
http://reblog.kondoumh.com/post/59828448393 | 2013-08-31 | 168 |
http://reblog.kondoumh.com/post/86791028732 | 2014-05-25 | 112 |
http://reblog.kondoumh.com/post/39637473249 | 2013-01-04 | 101 |
photo:
post_url | date | note_count |
---|---|---|
http://reblog.kondoumh.com/post/126011762237 | 2015-08-06 | 110 |
http://reblog.kondoumh.com/post/105334116637 | 2014-12-16 | 107 |
http://reblog.kondoumh.com/post/165475223402 | 2017-09-18 | 74 |
http://reblog.kondoumh.com/post/62335157286 | 2013-09-26 | 74 |
http://reblog.kondoumh.com/post/153985233752 | 2016-12-03 | 71 |
http://reblog.kondoumh.com/post/62874741172 | 2013-10-02 | 61 |
http://reblog.kondoumh.com/post/119751530162 | 2015-05-24 | 59 |
http://reblog.kondoumh.com/post/96782854287 | 2014-09-06 | 56 |
photo は天体ものが多い感じでした。
(5/6 追記)
ブラウザで動かしてたのを Node.js の CLI コマンドにしました。 最初 6700件ほどの処理を async await で同期的に書いたら、約20分かかりました。やはりある程度同時実行しないと時間かかります。定期実行して集計値のページ生成するなどの用途などでは AWS Lambda のようなサーバーレス構成には載せられない処理時間です。
ということで、フェッチ処理を並列化して、Promise.all() で待ち合わせるようにしたところ、15秒前後になりました。20件ずつなので、最大30多重ぐらいいく可能性があります。Tumblr API これぐらいなら平気で結果返してくれました。