pig's diary

何でも忘れるので万年初心者ね

Twitter検索系APIを触ったときの気づき

単にsearchAPIを触ってみましたという話なのですが。
jsonpで検索するしくみを作ってみました

数年遅れでSearchAPIの仕組みを知り、やられました

恥ずかしいかぎりです。いくつかはsearchAPIに限らないかもしれません。

  • OAuthを使わないAPIは、IP単位でアクセス数制限をかけているのですね・・・なんて頭がいいんだ。
  • search.twitter.comのAPIを叩いたとする。帰って来たデータに「next_page」があるかないかで、データがそれ以上あるかないかが分かる設計。(検索ヒット総数みたいなものが返って来ると思っていた私は豚顔)
  • その「next_page」には「"?page=2&max_id=40036130086715392&rpp=10&q=%23ogiri_110222"」のような文字列が入ってて、そのまま次の非同期通信に使える。
  • おまけに「max_id」がうまいこと効いている。これはpage1の最初のtweetがmax_idを下回るものになるよう設定するパラメータで、こうすることで以降のsearchの対象をずっと「同じ総体」として扱うことができる。同じmax_idをパラメータに入れる限り、page1の1個目は10分後も、1日後もきっとおなじtweet。この"くさび"がなければ、ページをめくるときに、取りこぼしや重複が生まれてしまうんだろう。

ちょっとしたツール

作業にあたり作ったツールです。よければご参考になさってください。JSONデータを整形したりするツールです。でもちょっとズルしています。無駄にビルトイン拡張しています。

// tweet本文に、リンクをつけます(urlとハッシュタグのみ)
String.prototype.getLinkedFormatted = function(){
    return this
        .replace( /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/g,
            '<a href=\"$&\" target=\"_blank\">$&</a>')
        .replace( /#([!-~]+) /g,
            '<a href=\"http://twitter.com/search?q=%23$1\" target="_blank">#$1</a> ')
        .replace(/(^\s+)|(\s+$)/g, "");
};
// 日付を「2分前」とかに変換します。
//(4日前位以前のデータは返ってこないみたいなので、これも無駄が多いかも知れません)
String.prototype.parseTimeBefore = function(){
    // get 'created_at' as this
    var c = Date.parse(this);
    if (typeof c === 'number'){
        var n = new Date().getTime(),
            s = Math.floor((n-c) / 1000);
        if      (s<60)                                  return [s, '秒前'].join('');
        else if (s>=60 && s<60*60)                      return [Math.floor(s/60), '分前'].join('');
        else if (s>=60*60 && s<60*60*24)                return [Math.floor(s/60/60), '時間前'].join('');
        else if (s>=60*60*24 && s<60*60*24*30)          return [Math.floor(s/60/60/24), '日前'].join('');
        else if (s>=60*60*24*30 && s<60*60*24*30*365)   return [Math.floor(s/60/60/24/30), 'ヶ月前'].join('');
        else if (s>=60*60*24*30*365)                    return [Math.floor(s/60/60/24/30/365), '年前'].join('');
    }
};
// 単純にGETパラメータStringから、オブジェクトを作ります。
String.prototype.toObj = function(){
    var s = this.replace(/\?/g,''),
        a = s.split('&'),
        o = {},
        t = [];
    for (var i=0;i<a.length;i++){
        t = a[i].split('=');
        o[t[0]] = t[1];
    }
    return o;
};

参考にしたページなど

API仕様書、Rate Limitingらへん

Anonymous calls are based on the IP of the host and are permitted 150 requests per hour. This classification includes unauthenticated requests (such as RSS feeds), and authenticated requests to resources that do not require authentication.
OAuth calls are permitted 350 requests per hour.

http://dev.twitter.com/pages/rate-limiting#rest

ためしに叩くとこうなる

▽叩くURI
http://search.twitter.com/search.json?callback=jQuery1506269263171396598_1298378483919&rpp=10&page=2&q=%23ogiri_110222&max_id=40028217674969088&_=1298378489954
▽返答(一部略)

{
    "results": [{
        "from_user_id_str": "93668795",
        "profile_image_url": "http://a2.twimg.com/profile_images/1229555096/images__2__normal.jpg",
        "created_at": "Tue, 22 Feb 2011 12:38:44 +0000",
        "from_user": "pomacho",
        "id_str": "40027709333573633",
        "metadata": {
            "result_type": "recent"
        },
        "to_user_id": null,
        "text": "オナニー中に親がやってきた!RT @ogiri_tweet: 【ついったー大喜利】2011年2月22日のお題です。PC操作中に「重大なエラーが発生したので強制終了します」。その理由とは? #ogiri_110222",
        "id": 40027709333573633,
        "from_user_id": 93668795,
        "geo": null,
        "iso_language_code": "ja",
        "to_user_id_str": null,
        "source": "&lt;a href=&quot;http://www.flight.co.jp/iPhone/TweetMe/&quot; rel=&quot;nofollow&quot;&gt;TweetMe for iPhone&lt;/a&gt;"
    },{...}],
    "max_id": 40028217674969088,
    "since_id": 0,
    "previous_page": "?page=1&max_id=40028217674969088&rpp=10&q=#ogiri_110222",
    "refresh_url": "?since_id=40028217674969088&q=#ogiri_110222",
    "next_page": "?page=3&max_id=40028217674969088&rpp=10&q=#ogiri_110222",
    "results_per_page": 10,
    "page": 2,
    "completed_in": 0.043587,
    "since_id_str": "0",
    "max_id_str": "40028217674969088",
    "query": "#ogiri_110222"
}

Firefoxアドオン「JSONView


JSONViewという、Firefoxアドオンが非常に便利でした。インデントしてカラーリングして表示してくれます。→

今後

TwitterAPIと仲良くなれた気がするので、StreamingAPI×node.jsとかに挑戦してみたいな。
目標:そろそろnode.jsについて一言書いておくか | KRAY Inc