※ 追記
ぞくへんかきました
PHP と Goutte ではじめる超絶簡単クローラー入門 ログイン編
Goutte とは
- PHP で書かれてるスクレイピングライブラリ
- CSS セレクタでかける
- jQuery になじみのあるみんなには簡単すぎる
導入
- composer つかおう(提案)
- composer インストールしてないひとはいますぐググろう(きっと Qiita にも記事あるよ!)
mkdir crawler && cd crawler
composer require fabpot/goutte
touch app.php
使い方
- さきほどこっそり touch した app.php にクローラをかいていこう
- 今回はClass Doctrine\DBAL\Schema\AbstractSchemaManager | Database Abstraction Layerからメソッドの一覧を
ぶっこぬいて拾い上げてみます
リクエストなげる
// 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";
});
});