SOFTELメモ

</> 技術者募集

【php】twitter Streaming API の statuses/filter を試す

問題

twitter Streaming API の statuses/filter って、どうやって使うのかな。

twitter-bird-white-on-blue

答え

Streaming API – 一度接続すると、延々とデータが流れてくる。

statuses/firehose だと、何でも全部取得できそうなのだが、特別な許可が必要らしい。

特に許可の必要のない statuses/filter を試してみる。

php

<?php

// OAuthのいつもの
$consumer_key = '********************';
$consumer_secret = '******************************************';
$oauth_token = '***************************************************';
$oauth_token_secret = '***********************************';

// APIのURL
$url = 'https://stream.twitter.com/1.1/statuses/filter.json';

// リクエストのメソッド
$method = 'GET';

// パラメータ
$post_parameters = array(
);
$get_parameters = array(
    'locations' => '132.2,29.9,146.2,39.0,138.4,33.5,146.1,46.20',
);
$oauth_parameters = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_nonce' => microtime(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_timestamp' => time(),
    'oauth_token' => $oauth_token,
    'oauth_version' => '1.0',
);

// 署名を作る
$a = array_merge($oauth_parameters, $post_parameters, $get_parameters);
ksort($a);
$base_string = implode('&', array(
    rawurlencode($method),
    rawurlencode($url),
    rawurlencode(http_build_query($a, '', '&', PHP_QUERY_RFC3986))
));
$key = implode('&', array(rawurlencode($consumer_secret), rawurlencode($oauth_token_secret)));
$oauth_parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $key, true));


// 接続&データ取得
// $fp = stream_socket_client("ssl://stream.twitter.com:443/"); でもよい
$fp = fsockopen("ssl://stream.twitter.com", 443);
if ($fp) {
    fwrite($fp, "GET " . $url . ($get_parameters ? '?' . http_build_query($get_parameters) : '') . " HTTP/1.0\r\n"
                . "Host: stream.twitter.com\r\n"
                . 'Authorization: OAuth ' . http_build_query($oauth_parameters, '', ',', PHP_QUERY_RFC3986) . "\r\n"
                . "\r\n");
    while (!feof($fp)) {
        echo fgets($fp);
    }
    fclose($fp);
}

上のソースの説明

条件は、ユーザー、キーワード、場所などが指定できる。

上の例では、日本語のツイートを集めてみようと思ったので、パラメータ locations を使って、下図あたりの位置を指定した。

tweet-range

リクエスト先のURLは以下のようになる(上図の四角の領域を、南西、北東、南西、北東…の緯度経度で指定する)。

https://stream.twitter.com/1.1/statuses/filter.json?locations=132.2,29.9,146.2,39.0,138.4,33.5,146.1,46.20

ブラウザでアクセスしてみると、ベーシック認証のダイアログが出てきて、ベーシック認証でいけてしまうようだが、ドキュメントに書いてあるとおりOAuthにする。

ちょっと試すだけなら、dev.twitter.com のOAuth Toolに、OAuthのAuthorizationヘッダに入れるデータを教えてもらうのもよし。よくあるOAuthのライブラリにお願いするのもよし。

上のソースでは、ライブラリなしで計算したので、上のソースだけコピー&貼り付けすれば、だいたい動作すると思う(主な処理は最後10行なのに、ほとんどOAuthの計算になってしまった)。


twitter APIからのレスポンスは、HTTPで延々と送られてくるので、fsockopen()やstream_socket_client()して接続して、一度fwrite()でHTTPリクエストを送信したら、fgets()で延々とレスポンスを取得し続ける。こちらから止めるか、twitter側から切られることで切断する。

twitter-stream-response


1つのアカウントで1つの接続しか作れないとのことなので、同じアカウントで複数のプログラムを動かそうとすると、後からつないだ方は、「Server overloaded, try again in a few seconds.」と言われて、「HTTP ERROR: 503」になる。

関連するメモ

コメント(1)

Twitterのstreamingを試そうとしてBad Requestにハマる | 生きる 2014年10月25日 22:15

[…] 【php】twitter Streaming API の statuses/filter を試す をコピペ参考にさせてもらって twitterのデータをストリーミングで受け取って 大量のデータであんなことやこんなことを・・・と妄想していました。 […]