技術めも

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