====== htmlSQLでプロ野球速報をWebスクレイピングして携帯のフルブラウザで見られるようにする実験 ======
[[http://www.jonasjohn.de/lab/htmlsql.htm|htmlSQL]]というPHPのWebスクレイピングライブラリがある。\\
ライセンスは修正BSDライセンス。\\
内部的には[[http://snoopy.sourceforge.net/|Snoopy]]のVersion1.01を使っている。(こちらはLGPLライセンス。バージョンがあがるとGPLになるみたい? 8-o)
これを使って何かしてみよう 8-)
例えば、携帯でプロ野球速報を見られるようにするのはどうだろう?
プロ野球速報と言えば[[http://www.nikkansports.com/baseball/professional/score/pf-score.html|nikkansports.com]]。\\
FLASH版のリアルタイム速報もhtml版の詳細な試合情報も重宝する。\\
しかし、これ(html版の方)を携帯で見ようとするとなかなか使い辛い。いわゆる携帯ブラウザでは見られないので、フルブラウザ(auだからPCサイトビューア。中身はOpera)で見ることになるが、重い重い 8-o \\
携帯のネットワークには情報量が多過ぎる。レンダリング負荷も高い。地下鉄で見ようものなら一苦労。
これをサクッと見られるようにスクレイピングしてみよう。\\
こんな感じで。
- スコア速報のページを取得
- お目当てのチームの試合詳細のページを探す
- 試合詳細から、見たい情報だけ取り出してhtmlにして出力
見てみると、nikkansports.comはhtml的になかなかよくできてる。\\
フォーマットはxhtmlだし(validじゃないけど)、class属性やid属性を誠実に付けている。文字コードがUTF-8なのも個人的にはありがたい。
100行くらいでできた。意外と簡単だね ^_^
できたソースコードはこんな感じ。中途半端にclass化したのはどんなもんだろう :-/ \\
_wsql = new htmlsql();
$this->_wsql->set_user_agent('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
if (!$this->_wsql->connect('url', NikkanScraper::DOMAIN . $src)){
throw new Exception('Error while connecting: ' . $this->_wsql->error);
}
}
public function query($sql) {
if ($this->_wsql->query($sql)) {
return $this->_wsql;
}
throw new Exception('Query error: ' . $this->_wsql->error);
}
public function showTable($whereClass, $showClass = '') {
$this->_wsql->query('SELECT * FROM table WHERE $class == "' . $whereClass . '"');
foreach($this->_wsql->fetch_array() as $row){
$data = mb_convert_kana(mb_ereg_replace('(……| )', '', $row['text']), 'k');
echo '';
}
}
}
?>
pb
connect('/baseball/professional/score/pf-score.html');
//全ての試合状態を取り出す
$statuses = $ns->query('SELECT text FROM h5');
foreach($statuses->fetch_array() as $row){
$allStatus .= $row['text'] . '
';
}
//試合詳細ページを1つずつ取得し、該当チームの試合詳細ページを探す
$links = $ns->query('SELECT href FROM a WHERE $text == "ニッカン式スコア"');
$hitFlg = false;
foreach($links->fetch_array() as $row){
$ns->connect($row['href']);
$detail = $ns->query('SELECT text FROM title');
$title = $detail->fetch_array();
//お目当てのチームを探す
if (mb_ereg($team, $title[0]['text'])) {
$hitFlg = true;
break;
}
}
if ($hitFlg) {
//詳細ページがあれば内容を表示
$ns->showTable('scoreTable', 'score'); //得点表
$ns->showTable('pitcher'); //投手情報
$ns->showTable('batter'); //打者情報
}
//全試合の状態を表示
echo $allStatus;
} catch (Exception $e) {
echo $e->getMessage();
}
?>