Laravel9でGuzzleを使用してスクレイピングをする

Laravel9でGuzzleを使用してスクレイピングをする Laravel

以前、Laravel8でGoutteを使用してスクレイピングをする記事を書きました。

使用しているライブラリ「Goutte」ですが、2022年10月現在で更新される気配がないので、2022年10月現在でも更新されている「Guzzle」を使用したいと思います。

環境

以下の環境で実装しています。
2022年10月に実装した時点の情報になります。

  • PHP:8.1.10
  • Laravel:9.31.0

Guzzleをインストールする

GitHub - guzzle/guzzle: Guzzle, an extensible PHP HTTP client
Guzzle, an extensible PHP HTTP client. Contribute to guzzle/guzzle development by creating an account on GitHub.

GitHubのページの通り、composerを使用してインストールができます。
下記の通り、実行してください。

composer require guzzlehttp/guzzle

僕が使用したLaravel9.31.0では、GuzzleがLaravelのパッケージに含まれていたので、実行すると更新される形になりました。

DomCrawlerをインストールする

一緒にDomCrawlerをインストールしておきます。
スクレイピングした結果をdom形式で扱いやすくするためです。

GitHub - symfony/dom-crawler: Eases DOM navigation for HTML and XML documents
Eases DOM navigation for HTML and XML documents. Contribute to symfony/dom-crawler development by creating an account on...

こちらもcomposerを使用してインストールができます。
下記の通り、実行してください。

composer require symfony/dom-crawler

Guzzleの使い方

本サイトのヘッダーに黒い背景で記載している
「フリーランスとしてリモートワークでWeb系のシステムエンジニアをやっている管理人がシステム開発関係について書いています」
という文言をスクレイピングして取得してみます。

スクレイピングの対象

サービスクラスを作成する

テスト時にモックを使えるように、スクレイピングする処理はサービスクラスで作成しました。

namespace App\Services;

use Symfony\Component\DomCrawler\Crawler;

class HogeService
{
    public function getContents()
    {
        $client = new \GuzzleHttp\Client();
        $response = $client->request('GET', 'https://specially198.com/');
        $crawler = new Crawler($response->getBody()->getContents());

        $header_text = $crawler->filter('#header-in > div');
        return $header_text->text();
    }
}

request関数でページの情報を取得し、filter関数でセレクタなどを指定して要素を取得する、という流れです。

DomCrawlerの詳細については以下の公式ドキュメントをご覧ください。https://symfony.com/doc/current/components/dom_crawler.html

サービスプロバイダに追加する

上記で作成したサービスクラスをサービスプロバイダに追加します。

public function register()
{
    $this->app->bind('HogeService', \App\Services\HogeService::class);
}

コントローラーからサービスクラスを呼び出す

コントローラーからサービスクラスを呼び出します。

$service = app()->make('HogeService');
$text = $service->getContents();
dd($text);

これで実行すると、以下のように本サイトのヘッダーからテキストを抽出できたことが確認できました。

スクレイピングの結果

テストを作成する

続いてはスクレイピングのテストです。
テストの場合は実際にスクレイピングせず、モックを使用するようにしてみます。

$mock = \Mockery::mock(HogeService::class)
    ->shouldReceive('getContents')
    ->andReturn('aaaaaaaaaaa')
    ->getMock();

$this->app->bind('HogeService', function() use ($mock) {
    return $mock;
});

$response = $this->get('/');

(アサートは省略)

モックを作成するには、Mockeryを使用します。
mock関数にサービスクラスを指定することで、対象のサービスクラスでモックを作成できます。

shouldReceive関数で指定するのが対象の関数名、andReturn関数で指定するのが関数の戻り値となります。
これで、スクレイピングをする関数を呼び出した際に、固定文字列を返すモックが作成できます。

作成したモックをサービスプロバイダに登録すると、テストの場合はモックに置き換わって処理されます。

テストを実行すると、以下のようにモックが使用されていることが確認できました。

スクレイピングでモックを使用する
タイトルとURLをコピーしました