※使用しているライブラリ「Goutte」ですが、2022年10月現在で更新される気配がないので、2022年10月現在でも更新されている「Guzzle」を使用して、スクレイピングする記事を書いたので、こちらをご覧ください。
Laravel8でスクレイピングを行う方法を紹介します。
PHPでスクレイピングというと様々なライブラリがありますが、本記事では「Goutte」を使用します。
Goutteをインストールする
・FriendsOfPHP/Goutte
https://github.com/FriendsOfPHP/Goutte
GitHubのページの通り、composerを使用してインストールができます。
下記の通り、実行してください。
$ composer require fabpot/goutte
Goutteの使い方
まずは、use文でライブラリを読み込みます。
use Goutte\Client;
続いて、実際にスクレイピングする方法です。
僕は競馬が好きなので、本記事ではJRAのホームページをスクレイピングしてみます。
同じページをCakePHP4でスクレイピングしたことがあるので、同様の手順で行います。
上記記事の手順と同様に、以下のコードを書きました。
$client = new Client();
$crawler = $client->request('POST', 'https://www.jra.go.jp/JRADB/accessT.html', ['cname' => 'pw03trl00/29']);
// 日付のブロックを取得
$crawler->filter('div.date_unit')->each(function ($elem_date_unit) {
$elem_date_h2 = $elem_date_unit->filter('div.block_header > div > h2');
preg_match('/(\w+)月(\w+)日/', $elem_date_h2->text(), $match_date);
// 開催場所のブロックを取得し、競馬場ごとに開催情報を登録
$elem_date_unit->filter('div.day_line.mt10 > div.rc')->each(function ($elem_rc) use ($match_date) {
$elem_rc_h3 = $elem_rc->filter('div > h3');
preg_match('/\d回(\D+)\d{1,2}日/', $elem_rc_h3->text(), $match_race_course);
$now = new \DateTime();
$year = date('Y');
$venue_date = $now->setDate((int) $year, (int) $match_date[1], (int) $match_date[2]);
logger("{$venue_date->format('Y-m-d')} {$elem_rc_h3->text()} {$match_race_course[1]}");
});
});
Goutteの場合、ポイントは以下の通りです。
- request関数で、ページの情報を取得
- filter関数で、セレクタなどを指定して要素を取得
Symfonyのコンポーネントを拡張しているようなので、各処理の詳細については、以下もご覧ください。
https://symfony.com/doc/current/components/dom_crawler.html
上記でログを出力すると、以下のように出力されます。
[2022-01-27 16:48:03] local.DEBUG: 2022-01-29 1回東京1日 東京
[2022-01-27 16:48:03] local.DEBUG: 2022-01-29 1回中京9日 中京
[2022-01-27 16:48:03] local.DEBUG: 2022-01-29 1回小倉5日 小倉
[2022-01-27 16:48:03] local.DEBUG: 2022-01-30 1回東京2日 東京
[2022-01-27 16:48:03] local.DEBUG: 2022-01-30 1回中京10日 中京
[2022-01-27 16:48:03] local.DEBUG: 2022-01-30 1回小倉6日 小倉