読者です 読者をやめる 読者になる 読者になる

メヘンニミン

たくさんの言語に触れたい.走り書きで見る整理ブログです.

Streaming APIで日本全国のツイートを収集する

PHP API

久々にまとまったネタです.

やりたいこと

日本全国のツイートを収集して分析して論文を書きたい(はやく).ツイートの再配布は利用規約で禁止されていますので,個人かつ無料でコーパスを構築する場合,自分で収集するしかありません.

例外の配布例.

Twitter Japan 株式会社 - 東日本大震災ビッグデータワークショップ - Project 311 -

ツイート本文を含まない配布コーパスの一例.

場所参照表現タグ付きコーパス Ver 0.1 (2015/05/25)

方法

Twitter Streaming APIPublic streams)を使います.今回は,PHPライブラリを使ってツイートデータを収集し,mongoDBやtxtファイルに書き出します.

Streaming APIは,ユーザにログインさせてアレコレするREST APIと比較して,API制限はありません(接続エラーは出ます).ポーリングの間,リアルタイムに発言された大量のツイートをざっと取ってきます.

Public streamsのページを見てみると,3種類のAPIがあることがわかります.

GET statuses / firehose

全タイムラインを取得する.ただこれ,申請が必要です.企業さん向けですね.GoogleNTTデータなどが使用しています.

Twitter、「NTTデータは今後もFirehoseを利用する」とGnipの発表に補足説明 - ITmedia ニュース

GET statuses / sample

全タイムラインから無作為に選ばれた1%を取得する.個人ではこちらになります.1%でも十分量なので…

POST statuses / filter

条件を指定して取得する.上記sample APIでも言語の指定ぐらいはできますが,こちらは検索キーワードや場所(区域),対象ユーザなども指定できます.

ということで,この記事ではsampleまたはfilterを用いたツイートの収集方法をまとめます.

実践

1. OAuth認証キーを取得する

Twitter Application Managementでアプリケーション登録を行います.方法はREST APIと同様なのでぐぐる.割愛.

2. Phirehoseで収集条件を指定する

Phirehose(GitHub)の[Download ZIP]からDL.以下を同じ場所に置きましょう.

  • libフォルダ
  • exampleフォルダの中にあるsample-en.php or filter-track.php

sample-en.phpの中身を見てみます.実のところ,やることはこれを書き換える作業です.

<?php
// (1) ライブラリを読み込む.参照先に注意.libフォルダとsample.phpが同じ場所にあるなら,「./lib/」に直す
require_once('../lib/Phirehose.php');
require_once('../lib/OauthPhirehose.php');

// (2) SampleConsumerクラス
class SampleConsumer extends OauthPhirehose
{
  public function enqueueStatus($status)
  {
    // $dataにツイートデータの連想配列が入る
    $data = json_decode($status, true);
    if (is_array($data) && isset($data['user']['screen_name'])) {
      // ツイート1つ1つにやりたいことをココに書く
      print $data['user']['screen_name'] . ': ' . urldecode($data['text']) . "\n";
    }
  }
}

// (3) 定数定義.認証キーを右の""の中に書く
define("TWITTER_CONSUMER_KEY", "");
define("TWITTER_CONSUMER_SECRET", "");
define("OAUTH_TOKEN", "");
define("OAUTH_SECRET", "");

// (4) 収集条件の指定
$sc = new SampleConsumer(OAUTH_TOKEN, OAUTH_SECRET, Phirehose::METHOD_SAMPLE);
// 下記の書き方でもOK
//$sc = new SampleConsumer('username', 'password', Phirehose::METHOD_SAMPLE, Phirehose::FORMAT_JSON, 'en');
// 言語の指定.日本語は'ja'にする
$sc->setLang('es');

// (5) 収集開始
$sc->consume();

filter-track.phpの中身もほぼ一緒で,(2)クラス名と(4)収集条件の箇所だけ違います.

<?php
// (2) FilterTrackConsumerクラス
class FilterTrackConsumer extends OauthPhirehose
{
}

// (4) 収集条件の指定.ツイート本文にmorning, goodnight, ...のいずれかを含むツイートを集める
$sc = new FilterTrackConsumer(OAUTH_TOKEN, OAUTH_SECRET, Phirehose::METHOD_FILTER);
$sc->setTrack(array('morning', 'goodnight', 'hello', 'the'));

非常にわかりやすいですね.得られるツイートデータは,REST APIのuser_timelineなどで得られるデータと同等です.

今回は,SampleConsumerクラスの中身を以下のように書き換えます.

<?php
class SampleConsumer extends OauthPhirehose
  public function init_db(){
    // mongoに接続
    $mongo = new Mongo();
    $db = $mongo->selectDB("db_tweets");
    $this->coll = $db->selectCollection("coll_tweets_sample");
  }
  
  public function enqueueStatus($status)
  {
    $this->init_db();
    
    $data = json_decode($status, true);
    if (is_array($data) && isset($data['user']['screen_name'])) {
      
      // 以下,mongoDBにinsertする場合
      if($this->coll != null){
        $this->coll->insert($data);
      }
      
      // 以下,txtファイルに書き出す場合
      // $put_data = mb_convert_encoding($data['user']['screen_name']
      //     ."\t".str_replace("\n", "", urldecode($data['text'])),"SJIS", "UTF-8")."\r\n";
      // file_put_contents("./tweets_sample.txt", $put_data, FILE_APPEND);
    }
  }
}

txtファイルに書き出す場合は,なにせデータが溜まるので注意してください.

3. 収集開始

準備ができたら,phpコマンドを叩いて放置!うまくいくでしょうか.

% php sample-en.php

ちなみに,sample APIの日本語指定で2日間(15/8/6~)収集したところ,ツイートはおよそ165万件(約12GB)溜まりました.多いな!!!

sample APIでも,replyをはじくなどして,収集目的に合わせてデータを絞りましょう.