TwitterAPIのユーザータイムライン(GET statuses/user_timeline)をデータベースに切れ目なく保存する(その1~since_idの活用)
目次
昨年、Twitter APIで取得したツィートの追加と削除を繰り返すための記事を書きました。
- PHPとMySQLを使ってTwitter APIで取得したツィートの追加と削除を繰り返す(その2~ステータスIDとsince_idについて)(新しいタブで開く)
- PHPとMySQLを使ってTwitter APIで取得したツィートの追加と削除を繰り返す(その3~データ追加のためのプログラミング)(新しいタブで開く)
その後、ツイートを「切れ目なく」データベースに追加するための、クエリ文(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という引数について考えてみます。
〔参考サイト〕