数年前のツイートも出てくるようになったツイッターの検索機能を使う
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;
}