たった10行のコードでひたすらアイドル水着画像をあつめる
こんにちは、飯塚です。
ウェブ上にはたくさんのデータがあふれています。その中から「自分の欲しいデータだけ」を「自動」でかき集めることができたら素敵じゃないですか? そこで今回は UT Startup Gym の「ウェブから情報をあつめる」で取り上げた内容をもとに、たった10行(正確には 9 行)のコードでひたすら「アイドル水着画像」を集める方法を紹介します。言語は PHP です!
さっそくコード書く
mac ユーザはさっそくプリインストールされているターミナル.app を起動して、
$ emacs crawler.php
と入力して Enter(もちろん他のエディタでも OK)。頑張って下のコード(青色のコメント部分は写さなくていいです)を写経してください。
<?php $url = "http://matome.naver.jp/odai/2135350364969742801"; // 画像を収集したい NAVER まとめページの URL $res = file_get_contents($url); // URL からソースコード(文字列)を取得する $dom = @DOMDocument::loadHTML($res); // 文字列から HTML を生成 $xml = simplexml_import_dom($dom); // さらにそこから SimpleXMLNode オブジェクトを取得 $imgs = $xml->xpath("//img[@class='MTMItemThumb']"); // XPath を用いて class="MTMItemThumb" の img 要素のみ取得 foreach ($imgs as $img) { // すべての画像について ... echo "<img src='".$img["src"]."'>\n"; // URL から img タグを出力 }
Windows ユーザは、各自 PHP を実行できる環境を整えてください。以前のエントリを参考に Ubuntu 入れちゃうのもアリです。
写経できたら、Ctrl+X を押して、Ctrl+S を押す(保存)。Ctrl+X を押して、Ctrl+C を押す(終了)。
画像の一覧を取得する
emacs が終了してシェル画面に戻ってきますので、次のコマンドを入力します。
$ php crawler.php
すると、画像の URL っぽいもの(正確に言うと img タグ)がたくさん表示されます!
これが実は、
http://matome.naver.jp/odai/2135350364969742801
に収められている画像の一覧なのです。
ブラウザに表示する
それでは、この画像群をブラウザで表示させます。もう一度ターミナルで、次のコマンドを入力します。
$ php crawler.php > photos.html $ open photos.html
すると、既定設定のブラウザが起動して、画像の一覧が表示されます。
おおおおー!
こんなかんじで色々な画像が集められます。
リンクをたどって、すべてのページから画像を収集する
先ほどのコードでは、1ページ目の画像しか収集することができなかったので、今回は2ページ目以降も収集してみたいと思います。
<?php $url = "http://matome.naver.jp/odai/2135350364969742801"; // NAVER まとめページ URL $res = @file_get_contents($url); while ($res) { $data = getData($res); foreach ($data["image"] as $image) { echo "<img src='".$image["src"]."'>\n"; } if ($data["nextPage"]) { // 次のページがあるか? $res = @file_get_contents($url."?page=".$data["nextPage"]); // URL の末尾に ?page= をつけると、ページを指定することができる。 sleep(1); // サーバへの負荷を減らすため 1 秒間遅延処理 } else { break; // 次のページがなければ終了 } } function getData ($html) { $dom = @DOMDocument::loadHTML($html); $xml = simplexml_import_dom($dom); $result["image"] = $xml->xpath("//img[@class='MTMItemThumb']"); $pager = $xml->xpath("//div[@class='MdPagination03']"); // ページ送り部分を取得 $current_page = $pager[0]->strong; // 太字のページ番号の値 $last_anchor = $pager[0]->a[count($pager[0]->a)-1]; // 太字でないページ番号の末尾の値 if ($last_anchor + 1 != $current_page) { // 太字のページ番号が最後のページを指していなければ... $result["nextPage"] = $current_page + 1; // 次のページを設定する。 } else { $result["nextPage"] = null; // 次のページは無い } return $result; }
ポイント
- URL の末尾に ?page= をつけると、ページを指定することができる。
- 実在するページ数より大きい値を指定した場合でも 404 エラー (Not Found) とならず、最終ページを表示する。
- そのため、?page= の指定を「404 エラーになるまでインクリメントする」戦略は使えない。
- したがって、ページ送りで、太字で強調されているページ番号が、太字じゃないページ番号の末尾の次ならば、最終ページと判断する。
まとめ
というわけで、今回は NAVER まとめのアイドル水着画像を題材に、データを収集する方法を紹介しました。
もちろんこの技術を応用すれば、ウェブサイトの構築や研究にも役立てることができます。もっと詳しく勉強したい人は、ぜひ XPath、クローリング、スクレイピングなどのキーワードでググってみてください。さらに詳しく知りたい人のために、講義資料はSlideShareでも公開しています。本格的にウェブサービスの構築について学びたい方は UT Startup Gym でお待ちしております。
それではまた!
ちなみに
- 実は http://imagero.us の作りかたです。
- ゆーすけべーさんのおっぱいエントリに触発されたようなされてないような