LaravelでGoutteを利用してWebスクレイピング


概要

スクレイピングする機会があったので調査メモです。
インストールから、実際に情報を取得し表示するところまで。

導入

インストール

$ composer require weidner/goutte

設定

config/app.php
'providers' => [
    Weidner\Goutte\GoutteServiceProvider::class,
]

'aliases' => [
   'Goutte' => Weidner\Goutte\GoutteFacade::class,
]

実装

コマンドを作成

php artisan make:command Scraping

実行名を設定

App\Console\Command\Scraping
protected $signature = 'command:scraping';

取得処理

Amazonの商品一覧ページを取得してみます。

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $goutte = GoutteFacade::request('GET', 'https://www.amazon.co.jp/gp/s/ref=amb_link_1?ie=UTF8&field-enc-merchantbin=AN1VRQENFRJN5%7CA1RJCHJCQT9WV5&field-launch-date=30x-0x&node=2494234051&pf_rd_m=AN1VRQENFRJN5&pf_rd_s=merchandised-search-left-4&pf_rd_r=6CWTB56SQ1GK6RA30VVV&pf_rd_r=6CWTB56SQ1GK6RA30VVV&pf_rd_t=101&pf_rd_p=f72beb25-a5bc-4658-9aa6-7d92f73c2c8b&pf_rd_p=f72beb25-a5bc-4658-9aa6-7d92f73c2c8b&pf_rd_i=637394');
        $goutte->filter('ul#s-results-list-atf')->each(function ($ul) {
            $ul->filter('li')->each(function ($li) {
                dd($li);
            });
        });
    }

実行してみる

$ php artisan command:scraping

とりあえず取得はできたみたいです。

商品の名前と値段とASINを取得してみる

先程のコードで商品ごとのリストアイテムタグは取得できているので、
各項目でどのように情報を取得するか確認しながら取ってみます。

商品の名前

aタグのプロパティでタイトルが取れそうなので、以下の手順で取ります。

  • aタグのクラスをfilterで取得
  • aタグのプロパティをattrで取得

実装

$li->filter('.s-color-twister-title-link')->attr('title')

商品の価格

こちらもクラスで取得してから、今度はテキストを取得します。

実装

$li->filter('.s-price')->text()

ASIN

アマゾンの商品識別コードです。

こちらは最初に取得したliのプロパティとして存在しています。

実装

$li->attr('data-asin')

完成形

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $goutte = GoutteFacade::request('GET', 'https://www.amazon.co.jp/gp/s/ref=amb_link_1?ie=UTF8&field-enc-merchantbin=AN1VRQENFRJN5%7CA1RJCHJCQT9WV5&field-launch-date=30x-0x&node=2494234051&pf_rd_m=AN1VRQENFRJN5&pf_rd_s=merchandised-search-left-4&pf_rd_r=6CWTB56SQ1GK6RA30VVV&pf_rd_r=6CWTB56SQ1GK6RA30VVV&pf_rd_t=101&pf_rd_p=f72beb25-a5bc-4658-9aa6-7d92f73c2c8b&pf_rd_p=f72beb25-a5bc-4658-9aa6-7d92f73c2c8b&pf_rd_i=637394');
        $goutte->filter('ul#s-results-list-atf')->each(function ($ul) {
            $ul->filter('li')->each(function ($li) {
                echo "-------------\n";
                echo 'タイトル:' . $li->filter('.s-color-twister-title-link')->attr('title') . "\n";
                echo '参考価格:' . $li->filter('.s-price')->text() . "\n";
                echo 'ASIN:' . $li->attr('data-asin') . "\n";
                echo "-------------\n";
            });
        });
    }

実行結果

実行してみます!

取れたは取れたんですが、なぜ4つ・・・?
ここはまだ調査をしてみます。