rcmdnk's blog

20150608_facebook_200_200

ちょっと前にFacebookのAPIの変更でシェア数の獲得方法が変更されたので このOctopressブログ用のものもアップデートしてみたんですが、 ちょっと色々問題があったのでアップデートしました。

変更点と問題点

シェア数を取ってくるには、以下の様なURLで最後のid以下の部分を自分が 知りたいURLにしてAPIを叩きます。

http://graph.facebook.com/?id=http://rcmdnk.github.io/blog/2014/02/19/computer-markdown/

すると、以前は下の様なJSONが帰って来ました。

{
  "id": "<URL>",
  "shares": 37
}

これがこの前から以下のように変更されています。

{
  "og_object": {
    ...
  },
  "share": {
    "comment_count": 0,
    "share_count": 37
  },
  "id": "http://rcmdnk.github.io/blog/2014/02/19/computer-markdown/"
}

実際にはAPIにいくつかバージョンが合って、 バージョン指定しないと使える最も古いものを使うのですが、 今回の変更で上の様なJSONを返していた部分を持っていたバージョンが削除され 下のような物を返すようになった、ということ。 (なので以前でも下の様な形で取ることは可能でした。) 最新のバージョンまでこれに関しては変更は今のところありません。

シェア数を取るには json_data["shares"]みたいにしてたのをjson_data["share"]["share_count"]に変更すればOK。

これで差し当たりぱっと取ってこれる事は出来るのですが、 新しくなってから、短期間で大量に取得しようとすると

(#4) Application request limit reached"

といったエラーを返す様になりました。 これはメッセージ通り回数制限にひっかかってしまっている状態で、 大体1分位で20~50回ほど一気に取ろうとすると引っかかる感じでした。

それでも5分くらいするとこの制限は解除される感じだっったので、 引っかかったらしばらく待機してまた取り始める、 みたいなことをやってみました。

と、スクリプトを流していると数時間終わらない様な状態だったので見てみると、 今度は403 Forbiddenを返していました。 何か書き間違えたか、でも最初の方は取れてたし、みたいなことを考えながら 直接ブラウザで開いたりしてみると常にこの状態。

https://google.comなどもだめ。ちょっと他の端末でみてみたところ 普通に見えました。

どうも短期間に大量に繰り返したため、制限を超えてブラックリスト入りみたいになって 端末ごとアクセスを拒否される様になってしまったようです。 ブラウザを変えたりしてもダメ。

この状態は結局2、3週間続いてやっと治りましたが、 何度もこの状態になったらずっと解除されないかも。

解決法

というわけで、制限を回避する方法を探してみましたが、 どうも簡単にはいかないようで、最終的にちょっとずつ取ってくる、という方法に。

octopress-share-numbers/share-numbers.rb

上のプラグインの中でやっていることですが、

  • 全てのページのURLリストを取ってきてソートして順にシェア数を獲得していく。
  • URLがキーで値が0のハッシュを作る。
  • 各URLについて1つずつチェックしていって値をアップデート。
  • errorが帰って来たらそこで終了。
  • どのURLのところで終了したか保存。
  • 値は各ページで使用出来るようにsite.configへ保存。
  • 別途JSON形式に直したものも保存しておく。
  • JSONの方は こんなファイルで出力させてページ作っておく。
source/facebook_shares.html
1
2
3
4
---
layout: raw
---
{{ site.facebook_shares_json }}
  • ここでのrawは以下の様にそのまま出力するようなレイアウト。
source/_layouts/raw.html
1
{{ content | expand_urls: root_url }}
  • 2回目以降はfacebook_shares.htmlをWebから取ってきて ハッシュを初期化。前回最後のURLもあるので、作成中のURLリストの 中でそのURLの所から始める。

と言った感じ。

Webでわざわざ公開してそこから持ってくる、みたいなちょっと面倒なことしてますが、 これはブログをビルド時に全て関連のことをやりたかったことと、 ビルドはwerckerを使ってHTMLになったものだけ 送る様になっているため、 ソースのレポジトリに残す、みたいなことが簡単に出来ないためです。

これだとたとえ1回50個のURLをアップデートしたとしても ブログポストだけで500位あると全部アップデートするのに10日もかかってしまいます。 が、まあとりあえずその程度でも良いかな。

もしもっと頻繁にアップデートしたかったら、 一日になんどもビルドするようにコミットし直す様にするか、 数のリストを作る作業を別途外部スクリプトにして どこかのマシンで定期的に実行してソースのレポジトリに保存して ビルド時にはそれを使う、みたいな事をすることも出来ます。

ただ、頻繁にやりたくても10分間隔とかだと確実にブラックリスト入するので もっと間隔を空ける必要がありますが、 1時間位だと大丈夫かどうか、ちょっと試してみないと分からないところです。 (一度入ってしまうとかなり長い期間使えなくなるので慎重に。。。)

色々見てるとWebサーバーサイドで直接コマンド打てる様な環境で、 5分おきにチェック、みたいのがあったりとかして、 この変更があってからはすぐにやっても意味が無いから感覚を伸ばしてチェック(それでも1時間とかではなく10分程度)、 みたいなことが書いてあるものをいくつか見ましたが、 そういう人達で既にブラックリスト入りしてる人はたくさんいるんだろうな、と。。。

Sponsored Links
Sponsored Links

« BSD(Mac)のsedでのタブ文字を変換する3つの方法 /bin/shと/bin/bashの違い(とcronでのシェル) »

}