LoginSignup
137
145

More than 5 years have passed since last update.

PHP と Goutte ではじめる超絶簡単クローラー入門

Last updated at Posted at 2015-05-14

※ 追記
ぞくへんかきました
PHP と Goutte ではじめる超絶簡単クローラー入門 ログイン編

Goutte とは

  • PHP で書かれてるスクレイピングライブラリ
  • CSS セレクタでかける
  • jQuery になじみのあるみんなには簡単すぎる

導入

  • composer つかおう(提案)
    • composer インストールしてないひとはいますぐググろう(きっと Qiita にも記事あるよ!)
mkdir crawler && cd crawler
composer require fabpot/goutte
touch app.php

使い方

リクエストなげる

// app.php
<?php

require_once __DIR__ . '/vendor/autoload.php';

$cli = new Goutte\Client();
$url = 'http://www.doctrine-project.org/api/dbal/2.4/class-Doctrine.DBAL.Schema.AbstractSchemaManager.html';
$crawler = $cli->request('GET', $url);

td.name に __construct とかいるのでこのへんを find する

  • こういうのは html みて規則を感じ取ろう
    • 習うより慣れろ 案件
<?php

// 前略
$crawler->filter('.name')->each(function($name) { // jQuery 脳で find しそうになる気持ちをぐっとこらえよう!
  echo $name->text(); // これだけで .name の中身が echo されるよ!かんたん!
});

余計なものたくさんあるからもっと絞り込んだほうがよさげ

  • こんな物量のスクレイピングにパフォーマンスとか気にする必要ないでしょ
<?php

// 前略
$crawler->filter('.name code a')->each(function($name) { 
  echo $name->text() . "\n";
});
__construct
Doctrine\DBAL\Connection
getDatabasePlatform
tryMethod
listDatabases
listSequences
Doctrine\DBAL\Schema\Sequence
listTableColumns
// 以下省略

なんてこった!それっぽくとれたとおもったら邪魔なやつがいるぜ!

  • 引数の型指定にはられてるリンクまでひろってしまった!
  • まぁいろんな方法があるとは思うのですが、今回のケースであればたとえば __construct なら
    • メソッド名の href: source-class-Doctrine.DBAL.Schema.AbstractSchemaManager.html#57-66
    • 引数型指定の href: class-Doctrine.DBAL.Connection.html
  • めんどくさいので href で判定してしまおう!
    • source-class からはじまってたらメソッド名ぽいのでこれで判定できるよね

ヤる

  • $name->attr(attrName) で attribute しゅとくできるよ
  • つまりこういうこと
<?php

// 前略
$href = $name->attr('href');
if (preg_match('/^source/' , $href)) { // source からはじまるものだけにしぼりこむ
  echo $name->text();
}

  • よいのでは
__construct
getDatabasePlatform
tryMethod
listDatabases
listSequences
listTableColumns
listTableIndexes
tablesExist
listTableNames
filterAssetNames
getFilterSchemaAssetsExpression
listTables
listTableDetails
listViews
listTableForeignKeys
dropDatabase
/// 以下略

最終的なコード

<?php

require_once __DIR__ . '/vendor/autoload.php';

$cli = new Goutte\Client();
$url = 'http://www.doctrine-project.org/api/dbal/2.4/class-Doctrine.DBAL.Schema.AbstractSchemaManager.html';
$crawler = $cli->request('GET', $url);

$crawler->filter('.name code a')->each(function($name) {
    $href = $name->attr('href');
    if (preg_match('/^source/' , $href)) {
        echo $name->text() . "\n";
    }
});

まとめ

  • クローラこんなに簡単につくれるけど悪いことにつかっちゃだめだよ!
  • dom 構造の規則が見えるようになるとさくさくいける
    • 習うより慣れろ(2回目)

番外編: よくある質問

  • Q: filter したときに例外かえってきて生きるのが辛いです
  • A: 例外吐くのは空の場合なので if ($hoge->count() === 0) でブロックしてから each するとよいでしょう
<?php

// 略
$crawler->filter('.name')->each(function($name) {
    $anchors = $name->filter('a');
    if ($anchors->count() === 0) {
        return;
    }
    $anchors->each(function($anchor) {
        echo $anchor->text() . "\n";
    });
});

137
145
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
137
145