1. TOPTOP
  2. Webサービス
  3. Twitter
  4. TwitterAPIのユーザータイムライン(GET statuses/user_timeline)をデータベースに切れ目なく保存する(その1~since_idの活用)

TwitterAPIのユーザータイムライン(GET statuses/user_timeline)をデータベースに切れ目なく保存する(その1~since_idの活用)

|

Twitter_logo_blue

keitaisokaiseki1

昨年、Twitter APIで取得したツィートの追加と削除を繰り返すための記事を書きました。

その後、ツイートを「切れ目なく」データベースに追加するための、クエリ文(MySQL)とプログラム(PHP)を考えてみました。

データベーステーブルの準備とクエリ文の発行

まずテーブルを作成します。

create table tweet (
	id int(11) not null auto_increment primary key,
	tw_id text,            //ステータスID
	tw_screen varchar(16), //スクリーンネーム
	tw_date varchar(25),   // ツイートした日時
	tw_txt text            // ツイート本文
);

そのテーブルにあらかじめ手動で最初のレコードを挿入します。これがないと、次のプログラミングコードにおいて、ツイートが取得できなくなります。

insert into tweet (tw_id, tw_screen, tw_date, tw_txt) values ('1', 'echizenya', '2012-06-12 11:00:00', 'test');

ここで入力しているステータスIDの番号は適当ですが、0だけはダメなようです。1以上にしてください。ちなみに日時も適当です。現在からみて、十分に古そうなのを選んでいます。

プログラミングコード

次にPHPのコードです。実行するとデータベースには、最新のツイートが3件が追加され、ブラウザには”done”という文字列が表示されます。

<?php

// データベースの接続
try {
	$dbh = new PDO('mysql:host=localhost;dbname=tweet1;charset=utf8', 'myusername','mypassword');
} catch(PDOException $e) {
	var_dump($e->getMessage());
	exit;
}

// もっとも大きい(新しい)ステータスIDをもつレコードを選ぶ
$sql = "select tw_id from tweet order by tw_id desc limit 1";
$stmt = $dbh->query($sql);

// ステータスIDを取得する
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $user) {
	// 0以上ではダメなので1以上にする
	if ($user['tw_id'] >= 1) {
		$sinceid_str = $user['tw_id'];
	}
	// 文字列型を整数型に
	$sinceid = intval($sinceid_str);
}

// 切断
$dbh = null;

// twitterAPIでユーザータイムラインを取得
require_once("twitteroauth/twitteroauth.php");

$consumerKey = "MYCONSUMERKEY";
$consumerSecret = "MYCONSUMERSECRET";
$accessToken = "MYACCESSTOKEN";
$accessTokenSecret = "MYACCESSTOKENSECRET";

$twObj = new TwitterOAuth($consumerKey,$consumerSecret,$accessToken,$accessTokenSecret);

$request = $twObj->OAuthRequest('https://api.twitter.com/1.1/statuses/user_timeline.json','GET',
	array(
		'count'=>'3',
		'screen_name' => 'echizenya_yota',
		'since_id' => $sinceid, // もっとも大きいステータスIDを引数にする
	));
$results = json_decode($request);

if(isset($results) && empty($results->errors)){
	foreach($results as $tweet) {
		try {
			$dbh = new PDO('mysql:host=localhost;dbname=tweet1;charset=utf8', 'myusername','mypassword');
		} catch(PDOException $e) {
			var_dump($e->getMessage());
			exit;
		}

		$stmt = $dbh->prepare("insert into tweet (tw_id, tw_screen, tw_date, tw_txt) values (:tw_id, :tw_screen, :tw_date, :tw_txt)");

		$stmt->bindParam(":tw_id", $tw_id);
		$stmt->bindParam(":tw_screen", $tw_screen);
		$stmt->bindParam(":tw_date", $tw_date);
		$stmt->bindParam(":tw_txt", $tw_txt);

		$tw_id = $tweet->id;
		$tw_screen = $tweet->user->screen_name;
		$tw_date = date('Y-m-d H:i:s', strtotime($tweet->created_at));
		$tw_txt = $tweet->text;

		$stmt->execute();
		$dbh = null;	
	}
} else {
	echo "関連したつぶやきがありません。";
}

echo "done";

ポイント

42行目でユーザータイムラインの引数のひとつである、since_id変数$sinceidを代入します。

そのために12行目でクエリ文を発行し、16行目から23行目のforeach文で$sinceidの値を取り出しています。

でもこれだけでは不可

これで、めでたしめでたし….。といきたいところですが、残念ながらこのPHPプログラミングコードだけでは、ツイートを切れ目なく格納することはできません。

データベースに連続したツイートが追加できなかったり、逆に重複したツイートが追加されたりもします。

Twitter APIのsince_idという引数には、独特のクセがあるためです。次回の記事(新しいタブで開く)は、since_idという引数について考えてみます。

〔参考サイト〕