全過去記事のTweet数を取得してみる

IMG_0671_retouch.jpg

TwitterのAPIは叩く回数をかなり厳しく制限されています。特にver.1.1以降はOAuth必須で各種APIエンドポイント毎に15分に15回、もしくは180回までしか叩けないという非常にキツい制限が掛かってしまいました。

参考:Twitter API 1.1への移行に際して #tweetbotjp .
http://togetter.com/li/463695

参考:Twitter APIと開発者規約変更のインパクトまとめ:結局、Twitter API 1.1で何が変わる? 5つのポイント
http://www.atmarkit.co.jp/ait/articles/1209/26/news120.html

でも、回数制限が掛かっていないAPIも存在するようです。それがこれ。

http://urls.api.twitter.com/1/urls/count.json

CDNに上がってるっぽいのはこれ。ssl版ですね。

https://cdn.api.twitter.com/1/urls/count.json

URLから察するにAPI 1.0っぽいけどまだ使えてます。
Tweetボタンに使っているAPIなので、そう安々と停止できないのかもですね。また、ディベロッパーガイドラインに載っていないAPIなので、利用していいものなのかが微妙な感じ。業務案件で使うとかはコンプライアンス的に避けたほうが無難でしょう。(ここで紹介するのはただの楽しいHackということで...)

MTで管理している全記事のTweet数を取得してみる

カスタムインデックステンプレートを追加します。内容は簡単です。

<MTEntries lastn="99999"><$mt:EntryPermalink$>
</MTEntries>

これだけ。あとは出力ファイル名を適当につけて、拡張子を.csvにして再構築しましょう。

次にphpでTweet取得スクリプトを書きます。

#!/path/to/php -q
<?php 
	switch($argc){
		case 1:
			echo "引数がたりないよ!読み込むCSV、書き込むCSVのファイルパスを指定してね" . "\n";
			echo "php gettweet.php PATH_TO_LOADFILE PATH_TO_WRITEFILE" . "\n";
			break;
		case 1:
			echo "引数がたりないよ!読み込むCSV、書き込むCSVのファイルパスを指定してね" . "\n";
			echo "php gettweet.php PATH_TO_LOADFILE PATH_TO_WRITEFILE" . "\n";
			break;
		default :
			echo $argc . "\n";
			echo "load from : " . $argv[1] . "\n";
			echo "save to :" . $argv[2] . "\n";
			getAllTweet($argv[1], $argv[2]);
			break;
	}
	function getAllTweet($filepath, $savepath){
		setlocale(LC_ALL,'ja_JP.UTF-8');
		$openfilepath = $filepath;
		$savefilepath = $savepath;
		$len = sizeof(file($openfilepath));
		$count = 0;
		$fp = fopen($openfilepath,"r");
		$result = fopen($savefilepath, "w");
		while($data = fgetcsv($fp, $len, ",")){
			$count++;
			$get_twitter = 'http://urls.api.twitter.com/1/urls/count.json?url=' . urlencode($data[0]);
			$json = file_get_contents($get_twitter);
			$json = json_decode($json);
			$tweets = $json--->{'count'};
			fputcsv($result, array($count, $tweets, $data[0]));
			echo "[".$count." / ".$len."] " . $tweets . " tweet: ".$data[0]."\n";
		}
		fclose($result);
		fclose($fp);
	}
?>

gettweet.phpてな感じで保存、

php gettweet.php path/to/load.csv path/to/save.csv

って感じで先ほどMTで書きだしたcsvのパスと取得したTweet数入りの記事URL一覧csvの書き出し先パスを指定すればモリモリ書き出されます。

ちなみにFacebookのいいね!数を同様に取得する際はこんな感じ。

#!/path/to/php -q
<?php 
	switch($argc){
		case 1:
			echo "引数がたりないよ!読み込むCSV、書き込むCSVのファイルパスを指定してね" . "\n";
			echo "php getlike.php PATH_TO_LOADFILE PATH_TO_WRITEFILE" . "\n";
			break;
		case 1:
			echo "引数がたりないよ!読み込むCSV、書き込むCSVのファイルパスを指定してね" . "\n";
			echo "php getlike.php PATH_TO_LOADFILE PATH_TO_WRITEFILE" . "\n";
			break;
		default :
			echo $argc . "\n";
			echo "load from : " . $argv[1] . "\n";
			echo "save to :" . $argv[2] . "\n";
			getAllLikes($argv[1], $argv[2]);
			break;
	}
	function getAllLikes($filepath, $savepath){
		setlocale(LC_ALL,'ja_JP.UTF-8');
		$openfilepath = $filepath;
		$savefilepath = $savepath;
		$len = sizeof(file($openfilepath));
		$count = 0;
		$fp = fopen($openfilepath,"r");
		$result = fopen($savefilepath, "w");
		while($data = fgetcsv($fp, $len, ",")){
			$count++;
			$get_like = 'https://graph.facebook.com/' . urlencode($data[0]);
			$json = file_get_contents($get_like);
			$json = json_decode($json);
			$likes = $json--->{'shares'};
			fputcsv($result, array($count, $likes, $data[0]));
			echo "[".$count." / ".$len."] " . $likes . " likes: ".$data[0]."\n";
			sleep(1);
		}
		fclose($result);
		fclose($fp);
	}
?>

APIのパス以外ほぼ同じだけど、whileループの末尾にsleep(1);追加してるのがミソ。
FacebookのAPIは600秒に600回までしか叩けない仕様になってるっぽく、これ入れないと記事が多い場合に途中で怒られます。