読者です 読者をやめる 読者になる 読者になる

たった数行のコードでひたすらアイドル水着画像をあつめるのをGoutteで書いてみた

PHP

あくまで勉強になると思って、あくまで勉強になると思って、Goutteでやってみました。

Goutteはfabpot先生によるクローラライブラリです。Goutte.pharというファイルを1つダウンロードしてくるだけで使えます。詳しくはid:hnwのすばらしい解説をどうぞ。

で、こんな感じ。

<?php
require __DIR__ . '/goutte.phar';
(new Goutte\Client)
    ->request('GET', 'http://matome.naver.jp/odai/2135350364969742801')
    ->filter('img.MTMItemThumb')
    ->each(function ($node) {
        echo $node->ownerDocument->saveHTML($node), "\n";
    });

DOMElementを元の文字列にするのに、$node->ownerDocument->saveHTML($node)という書き方があることを知ったことが最大の発見でした。

しかし、サムネイルを表示するだけで良いのだろうか。やはりクリックしたら元画像に飛んだほうが実用的もといより勉強になるのではないか。

<?php
require __DIR__ . '/goutte.phar';
(new Goutte\Client)
    ->request('GET', 'http://matome.naver.jp/odai/2135350364969742801')
    ->filter('img.MTMItemThumb')
    ->each(function ($node) {
        echo $node->ownerDocument->saveHTML($node->parentNode), "\n";
    });

よさそうなので、2ページ目以降も取れるようにしてみます。

<?php
require __DIR__ . '/goutte.phar';
$client = new Goutte\Client;
$crawler = $client->request('GET', 'http://matome.naver.jp/odai/2135350364969742801');
while (1) {
    $crawler->filter('img.MTMItemThumb')
        ->each(function ($node) {
            echo $node->ownerDocument->saveHTML($node->parentNode), "\n";
        });

    $nextPage = $crawler
        ->filter('div.MdPagination03 strong')->nextAll()->text();
    sleep(1);
    $crawler = $client->request('GET', "http://matome.naver.jp/odai/2135350364969742801?page=$nextPage");
}

filter('div.MdPagination03 strong')で現在のページを掴んで、nextAll()で後続を全部ひろって、text()で最初の要素のテキストを取ってます。

じゃあこの無限ループいつ終わるのかというと、nextAll()が空の時にtext()が例外で終了します。手抜きですが実用的なのでいいんです。