Twitterで特定の人の発言を捕捉するクライアント-ソース編-
昨日のエントリーで書いた、特定の人の発言を捕捉するサイトのソースを曝しておきます。
全く高度なことはやっていないので、みればすぐにわかるかと思います。
作成意図は、面白いことを言う人や、情報系Botの発言を追跡するためのものです。
なので、発言機能などはありません。
みーてーるーだーけー。の状態です。
ドコモ専用です。
IDとパスワードは将来の拡張用です。
画像のPNG→Jpegを行うファイルの名前が逆です。
間違ってます・・・。
サイトメイン
- oreore.xhtml
<?php header("Content-type: application/xhtml+xml" ); require_once './OreOreTwitter.php'; //将来用の設定 define("USER","ID"); define("PASS","PASS"); //さかのぼる最大のページ数を指定 define("MAX_PAGE", 10); //ページ送り・戻しを作成 function makeArrow($sname, $page=1){ $arrow = "<div style=\"text-align:center;\">\n"; if($page == 1){ $arrow .= "<a href=\"./?sname={$sname}&page=". ++$page ."\"> >> </a>"; }elseif($page > 1 && $page < MAX_PAGE){ $tPage = $page; $arrow .= "<a href=\"./?sname={$sname}&page=". --$page ."\"> << </a><a href=\"./?sname={$sname}&page=". ++$tPage ."\"> >> </a>"; }elseif($page == MAX_PAGE){ $arrow .= "<a href=\"./?sname={$sname}&page=". --$page ."\"> << </a>"; } $arrow .= "\n</div>\n"; return $arrow; } //確認したいユーザの名前を列挙 //TODO:外部から読み込めるように $friends = array("ID1","ID2"); $options = ""; //リストの作成 foreach($friends as $friend){ $options .= "<option value=\"{$friend}\">{$friend}</option>\n\t\t\t\t\t"; } $userTl = ""; $screenName = ""; $dispName = ""; //送信されたデータを取得 if(isset($_GET["sname"])){ $screen_name = $_GET["sname"]; $page = (isset($_GET["page"])) ? $_GET["page"] : 1; $arrow = makeArrow($screen_name, $page); //タイムラインを取得 $screenName = $screen_name; $oreore = new OreOreTwitter(USER,PASS); $oreore->setScreenName($screenName); $body = $oreore->getResDom($page); $image = mb_convert_encoding($oreore->getUserImage($body), "SJIS", "UTF-8"); $tls = $oreore->getFriendTimeLine($body, $page); //PNG形式の画像だったら変換するようにアドレスを変更 $imageUrl = (ereg(".+.(jpg|jpeg)$", $image)) ? $image : "./jpToPn.php?iurl={$image}"; $dispName = "<br />\n<img src=\"{$imageUrl}\" width=\"50px\" height=\"50px\"/><br />\n"; $dispName .= "<span style=\"color:orange;\">★</span>現在{$screenName}さんを表示中\n"; $userTl .= "<div style=\"font-size:small;\">\n"; //タイムラインを整形する foreach($tls as $tl){ $tml = mb_convert_encoding($tl["message"], "SJIS", "UTF-8"); $tml .= "\n<br />\n<div style=\"text-align:right; color:gray;\">".$tl["date"]."</div>\n"; $userTl .= "{$tml}\n<hr />\n"; } $userTl .= $arrow; $userTl .= "</div>\n"; } print <<< EOD <?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.3) 1.0//EN" "i-xhtml_4ja_10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-Type" content="application/xhtml+xml; charset=Shift_JIS" /> <title>Stokker for mobile</title> </head> <body style="background-color:rgb(154,228,232);"> <div style="text-align:center;"> <br /> <form action="./" method="get"> <select name="sname"> {$options} </select> <input type="submit" value="追跡" /> </form> {$dispName} <hr /> </div> <br /> {$userTl} <br /> <span style="font-size:small;"> Copyright © 2008 YUTA. All Rights Reserved. </span> </body> <html> EOD; ?>
Webをスクレイピングして特定ユーザの発言を連想配列で返す
- OreOreTwitter.php
<?php require_once 'HTTP/Request.php'; define("USER_TIMELINE","http://twitter.com/"); class OreOreTwitter{ protected $userId; protected $password; protected $screenName = ""; //IDとPASSは将来の拡張用 public function OreOreTwitter($userId = "", $password = ""){ $this->userId = $userId; $this->password = $password; } //取得するユーザIDを設定 public function setScreenName($screenName){ $this->screenName = $screenName; } //ユーザタイムラインのDOMを取得 public function getResDom($page = 1){ if($this->screenName == ""){ throw new Exception("Screen Name is NOT SET"); } $request = new HTTP_Request(USER_TIMELINE . $this->screenName . "?page=" . $page); $respons = $request->sendRequest(); if(PEAR::isError($respons)){ throw new Exception("Timeline get ERROR"); } $dom = @DOMDocument::loadHTML($request->getResponseBody()); return $dom; } //ユーザのアイコンのアドレスを取得 public function getUserImage($body){ $xml = simplexml_import_dom($body); $image = $xml->xpath("//h2[@class=\"thumb\"]"); return (string)$image[0]->a[0]->img[0]["src"]; } //フレンドタイムラインから発言などを取得 public function getFriendTimeLine($body, $page){ $xml = simplexml_import_dom($body); $contents = array(); $i = 0; //どのページでも最新の発言が表示されるため2ページ目以降では除去 if($page == 1){ //各エントリを取得 $entry_top = $xml->xpath("//div[@class=\"desc hentry\"]"); //発言を取得 $content = strip_tags($entry_top[0]->p[0]->asXML()); $time = $entry_top[0]->xpath("p[@class=\"meta entry-meta\"]"); $time = $this->getJpTime((string)$time[0]->a[0]->abbr[0]["title"]); $contents[$i++] = array("message"=>$content, "date"=>$time); } $entry_array = $xml->xpath("//td[@class=\"content\"]"); foreach($entry_array as $entry){ $time = $this->getJpTime((string)$entry->span[1]->a[0]->abbr[0]["title"]); $content = strip_tags($entry->span[0]->asXML()); $contents[$i++] = array("message"=>$content, "date"=>$time); } return $contents; } //時刻の形式を日本時間へ変換 protected function getJpTime($originTime){ return date("Y/m/d H:i:s",strtotime($originTime)); } } ?>
PNGからJPEGに変換
- jpToPn.php
<?php //PNGをJpegに変換 //GDモジュールがPNGをサポートしてないと動かない if(isset($_GET["iurl"])){ header("content-type: image/jpeg"); //TODO 作成するJpeg画像のサイズを指定できるように $image = imagecreatefrompng($_GET["iurl"]); imagejpeg($image); imagedestroy($image); } ?>