Twitter Blog: Now showing: Older Tweets in search results つまり、ツイッターのツイート検索で昔のツイートも出てくるようになったよ という事。 APIからは使えないみたいなので、APIを作りました。 ただ、https://twitter.com/のcookieが必要だから普通のツイッターアプリと同じようには無理。 検索キーワードはこれが使えるUsing the Twitter Search API | Twitter Developers
使い方は、第一引数に検索キーワード。 第二引数にhttps://twitter.com/のauth_tokenのcookie。ブラウザを開いて各自調べて下さい。正規表現的に
[0-9a-f]{40}こんな文字列でした。 第三引数は検索タイプ。recentとrelevanceがあってtrueならrecent。 recentにしても日付順全てのツイートが出てくるのは最近一週間だけで、それ以前はrecentもrelevanceも同じようなツイートが返ってきます。 第四引数はmax_id。これで順番に受信する。
検索タイプがrecentで投稿日が一週間以内のツイートは条件にマッチする物が全て取得出来るけど、それ以外は飛び飛びでしか取得出来なかったりと完全ではない。 でもuntilキーワードを付けたりで工夫は出来る。Twitter / Search - 古アニMAX until:2010-11-10…けど完全に取る事は出来ないみたい。インデックスされてないだけでそのうち出来るようになるかな? Twitter / Search - from:jp_trends until:2011-05-31jp_trendsは2011/04/12にアカウントを取って即サービスインしたと思うけど、現時点(2013/02/08 18:05)では検索結果が0件。さてどうなるか。
$max_id=null; $resultAll=[]; do{ $results=tweetSearch("フルアニMAX","*****",true,$max_id); $resultAll+=$results->results; $max_id=$results->since_id; print "get ".count($resultAll)." items. ".end($results->results)->created_at." {$max_id}n"; }while(1<count($results->results) ); foreach($resultAll as $result){ print $result->created_at." ".mb_substr($result->text,0,70,"ASCII")."n"; } print "total ".count($resultAll)." items.n"; function tweetSearch($keyword,$oauthToken,$isRecent=true,$max_id=null){ $options = array( 'http'=>array( 'method' => "GET", 'header' => [ "cookie: auth_token={$oauthToken};", ] ) ); $prams=[]; $prams["src"]="typd"; $prams["type"]=$isRecent?"recent":"relevance"; $prams["include_available_features"]="1"; $prams["include_entities"]="1"; if($max_id!==null){ $prams["max_id"]=$max_id; } $prams["count"]="100"; $prams["q"]=$keyword; $context = stream_context_create($options); $retry=5; do{ $result = @file_get_contents("https://twitter.com/i/search/timeline?".http_build_query($prams), false, $context); if($result!=""){ break; } }while($retry--); $result=json_decode($result); $resultItems=explode('<li class="js-stream-item',$result->items_html); $results=(object)null; $results->results=[]; $results->since_id=""; foreach($resultItems as $resultItem){ $add=(object)null; $add->user=(object)null; if(!preg_match('{data-item-id="(d+)"}',$resultItem,$match)){continue;} $add->id_str=$match[1]; if(!preg_match('{<p class="js-tweet-text">(.+?)</p>}s',$resultItem,$match)){continue;} $add->text=$match[1]; $add->text=preg_replace_callback('{<a .*?</a>}',function($p){ $html=$p[0];$return=$html; if(preg_match('{data-expanded-url="(.+?)"}',$html,$match)){ $return=html_entity_decode($match[1]); }else if(preg_match('{>(pic.twitter.com/w+)</a>}',$html,$match)){ $return="http://{$match[1]}"; } return $return; },$add->text); $add->text=strip_tags($add->text); if(!preg_match('{data-time="(d+)"}s',$resultItem,$match)){continue;} $add->created_at=date("c",$match[1]); if(!preg_match('{data-screen-name="(.*?)"}s',$resultItem,$match)){continue;} $add->user->screen_name=$match[1]; if(!preg_match('{data-name="(.*?)"}s',$resultItem,$match)){continue;} $add->user->name=$match[1]; if(!preg_match('{data-user-id="(.*?)"}s',$resultItem,$match)){continue;} $add->user->id_str=$match[1]; $results->results[$add->id_str]=$add; $results->since_id=$add->id_str; } return $results; }