前から興味があったけどやったことがなかったPHPでのWebスクレイピング。調べてみると、『PHP Simple HTML DOM Parser』というのがいいらしい(参考:PHP Simple HTML DOM Parserの使用方法 – Webスクレイピング ライブラリ)。
PHP Simple HTML DOM Parser – Browse Files at SourceForge.net
というわけで使ってみることに。まずは上記ページからsimple_html_dom.phpをダウンロードして作成するPHPと同じフォルダに置く。今回のウェブスクレイピングの対象ページははてなブックマークのタグ検索ページ。はてブのタグ検索結果ページのそれぞれのエントリーはsearch-resultというクラスのliタグ内に記述しているようなので、search-resultクラスの要素を取得してforeachでループしたらよさそう。
やってみたら思った以上に簡単にできたので、ちょっといろいろ機能つけくわえてみた。以下、body部分のみ抜粋。
<body>
<?php
// タグの指定
$tag = "";
if( isset($_GET["tag"]) ){
$tag = $_GET["tag"];
}
// 除外URLの指定
$cut_url = "";
if( isset($_GET["cut"]) ){
$cut_url = $_GET["cut"];
}
// 指定ユーザー数
$users = 3;
if( isset($_GET["users"]) && is_numeric($_GET["users"])){
$users = $_GET["users"];
}
?>
<form>
<label>タグ名:<input type="text" name="tag" value="<?php echo $tag; ?>"></label><br>
<label>除外URL:<input type="text" name="cut" value="<?php echo $cut_url; ?>"></label><br>
ブックマーク数:
<select name="users" data-value="<?php echo $users; ?>">
<option value="1">1 user</option>
<option value="3">3 users</option>
<option value="5">5 users</option>
<option value="10">10 users</option>
<option value="50">50 users</option>
<option value="100">100 users</option>
<option value="300">300 users</option>
<option value="500">500 users</option>
</select>
<input type="submit">
</form>
<ul id="hatebu_list">
<?php
require_once 'simple_html_dom.php';
$page_cnt = 0;
$page_step = 40;
$page_last = 160;
if($tag != ""){
for($page_cnt=0; $page_cnt<=$page_last; $page_cnt+=$page_step){
$hatebu = file_get_html( 'http://b.hatena.ne.jp/search/tag?safe=off&q=' . urlencode($tag) . '&users=' . $users . '&of=' .$page_cnt );
?>
<?php foreach ($hatebu->find( '.search-result' ) as $e) :?>
<?php
$url = $e->find('h3 a', 0)->href;
if( ($cut_url != "") && (strpos($url, $cut_url) !== false) ){
continue;
}
?>
<li>
<a href="<?php echo $url; ?>" target="_blank"><?php echo $e->find('h3 a', 0)->title; ?></a>
<a href="http://b.hatena.ne.jp<?php echo $e->find('.users a', 0)->href; ?>" target="_blank" class="users"><?php echo $e->find('.users a', 0)->plaintext; ?></a>
</li>
<?php endforeach; ?>
<?php
$entry_count = count( $hatebu->find( '.search-result' ) );
$hatebu->clear();
// エントリー数が少なければ抜ける
if($entry_count < $page_step){
break;
}
}
}
?>
</ul>
<script>
var users = document.getElementsByName('users')[0];
users.value = users.getAttribute('data-value');
</script>
</body>
サンプルページ:スクレイピングテスト
内容としては、タグと除外URLを入力してブックマーク数を指定して送信ボタンを押すとはてなブックマークのタグ検索の結果(最高200件まで)を出力するというもの。除外URLを入力すると、表示させないエントリーを指定できる。
例えば、タグに『ニコニコ動画』、除外URLに『http://www.nicovideo.jp/』と入れると、結果はURLに『http://www.nicovideo.jp/』がURLに入ってないエントリーだけが表示される(前方一致ではなく、URLのどこかに含まれていたら除外する)。
とりあえず、5ページぐらいなら怒られないだろうと思って最初5ページのみを見るようにした。他に影響がでるもんでもないと思うので、XSSとか考えずにコーディングしてます(それ以前にもっとキレイなコードを書くようにしろと怒られそうですが・・・)。
本当、思った以上に簡単にできたので時間があれば何かウェブサービスっぽいものを作ってみたい。

コメント