▶ 技術めも
Goutte めも
基本
$client = new Goutte\Client();
// GET
$client->request('GET', 'http://example.com/some/url');
// POST
$client->request('POST', 'http://exmaple.com/some/post/url', ['foo' => 'bar'], ['image' => '/var/www/myimage.jpg']);
// timeout
$client = new Goutte\Client();
$guzzleClient = new GuzzleHttp\Client([
'timeout' => 1,
]);
$client->setClient($guzzleClient);
// リクエストヘッダ
$client->setHeader('User-Agent', 'TEST');
// レスポンス ボディの取得
$resBody = $client->getInternalResponse()->getContent();
// ステータス コードの取得
$resStatus = $client->getInternalResponse()->getStatus();
// レスポンス ヘッダの取得
$resHeaders = $client->getInternalResponse()->getHeaders();
var_dump($resHeaders['Content-Type'][0]);
comporser.json
"require": {
"fabpot/goutte" : "3.1.2"
}
SAMPLE
要素取得
$client = new \Goutte\Client();
$client->setHeader('X-Nantoka-Id', 'abcd0123');
$page = $client->request('GET', 'http://xxxx.xxxx.jp/');
$page->filter('h2')->each(function ($node) {
echo $node->text() . "\n";
echo $node->html() . "\n";
});
Cookie
// クッキーをファイル保存しておく
$cookies = $client->getCookieJar()->all();
file_put_contents(self::COOKIE_FILE, serialize($cookies));
// ファイル保存してたクッキーをセットする
$cookies = unserialize(file_get_contents(self::COOKIE_FILE));
if (! empty($cookies)) $client->getCookieJar()->updateFromSetCookie($cookies);
User-Agent 変更
$client->setHeader('User-Agent', 'abc123');
$client->setServerParameter('HTTP_USER_AGENT', 'abc123');
リダイレクタ回数
$client->setMaxRedirects(1);
// 最後に辿り着いたURL
$client->getRequest()->getUri();
ログイン(?)
$client = new \Goutte\Client();
$page = $client->request('GET', 'https://XXXXX/login');
$form = $page->selectButton('ログイン')->form();
$form['_account'] = 'IDIDID';
$form['_password'] = 'PASSPASS';
$page = $client->submit($form);
$body = $page->html();
var_dump( $body );
リンククリック
$link = $page->selectLink('次へ')->link();
$page = $client->click($link);
最終ページ確認
try {
$link = $page->selectLink('次のページ')->link();
$page = $client->click($link);
} catch (\InvalidArgumentException $e) {
break;
}
eachで配列取得
$page = $client->request('GET', 'http://example.com/');
$videos = $page->filter('video')->each(function( $node ){
return [
'poster' => $node->attr('poster'),
'src' => $node->attr('src')
];
});
アクセス先の特定のタグの内容・属性を取得
$client = new \Goutte\Client();
// $crawlerは\Symfony\Component\DomCrawler\Crawler
$crawler = $client->request('GET', 'http://example.com/some/url');
// </h1>タグの内容
$crawler->filter('h1')->text();
// <h2>>タグのhref属性
$crawler->filter('h2 a')->attr('href');
// 全部のliタグの内容
$lists = $crawler->filter('ul li')->each(function(Crawler $node){
return $node->text();
});
// 取得したHTML全体
$crawler->html();
アクセス先にあるリンクをクリックする
$client = new \Goutte\Client();
// まずリンクのあるURLにアクセス
$crawler = $client->request('GET', 'http://example.com/some/url');
// 「ここをクリック」をクリックしてリンク先に遷移
$client->click($crawler->selectLink('ここをクリック')->link());
form送信
// 「ログイン」というボタンクリックで送信されるフォームを選択
$form = $page->selectButton('ログイン')->form();
$params = ['username' => 'username', 'password' => 'password'];
$page = $client->submit($form, params);
$body = $page->html();
オブジェクト
$client - Goutte\Client
ブラウザに相当
- followRedirects($followRedirect) 自動的にリダイレクトするかどうか設定する(デフォルトでは自動でリダイレクトする)
- click($link) リンクをクリックする
- submit($form, $values) フォームを送信する
- request($method, $uri, $parameters, $files, $server, $content, $changeHistory) HTTPリクエストを行う
- back() ブラウザの履歴を利用して前のページに戻る
- forward() ブラウザの履歴を利用して次のページに進む
- reload() 今のページをリロードする
- followRedirect() リダイレクト先に遷移する
$crawler
WEBページ/データ抽出
ノードの絞り込みに利用できるメソッド
- filter('h1') CSSセレクタにマッチするノード
- filterXpath('h1') XPath式にマッチするノード
- eq(1) 指定したインデックスのノード
- first() 最初のノード
- last() 最後のノード
- siblings() 兄弟のノード
- nextAll() 後の兄弟ノード
- previousAll() 前の兄弟ノード
- parents() 親ノード
- children() 子ノード
- reduce($lambda) callableがfalseを返さないノード
- selectLink($value) 指定されたテキストを含むリンクすべてを選択
- selectButton($value) 指定されたテキストを含むボタンすべてを選択
情報の抽出に利用できるメソッド
- attr($attribute) 最初のノードの、指定した属性の値を返す
- text() 最初のテキストノードの値を返す
- extract($attributes) すべてのノードから、配列で指定した属性の値を抽出する(_textはテキストノードの値の意味)
リンクやフォームに対応するオブジェクトを取得
- form() 最初のノードが含まれているフォームに対応するFormオブジェクトを返す
- link() 最初のノードに対応するLinkオブジェクトを返す
filter
$spans = $node->filter('div.a-spacing-mini div.a-spacing-mini')->eq(0)->filter('span.a-size-small');
foreach ($spans as $span) {
echo trim($span->nodeValue).PHP_EOL; // $span は php DOMElement になってしまう
}
LINK
- WebスクレイピングライブラリGoutteで遊んでみる
- http://qiita.com/mojibakeo/items/be68498764909a66f126
- http://qiita.com/77web@github/items/3cd3b56985d5c6845661
- http://docs.symfony.gr.jp/symfony2/components/dom_crawler.html
- http://blog.asial.co.jp/1316
https://designhack.slashlab.net/note-for-make-full-use-of-goutte-php-web-scraper/