Edited at

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

More than 3 years have passed since last update.

※ 追記

ぞくへんかきました

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";
});
});