Published on

laravelでスクレイピングする方法、データ保存、定期実行まで

目次

laraveでスクレイピングして結果を保存、定期的に実行させるところまで説明します。

実際のコード

laravelが導入してあることが前提で話を進めていきます。

ライブラリインストール

スクレイピングはGoutteを使用します。

https://github.com/dweidner/laravel-goutte

作成したプロジェクトまで移動してインストールします。

composer require weidner/goutte

config/app.phpを編集します。
providersとaliasesに追加します。

// config/app.php

return [

// ...

'providers' => [

// ...

/* * Package Service Providers... */ Weidner\Goutte\GoutteServiceProvider::class, // [1] ],

// ...

'aliases' =>

// ...

'Goutte' => Weidner\Goutte\GoutteFacade::class, // [2] 'Hash' => Illuminate\Support\Facades\Hash::class, ],

];

controllerに処理をかく

次にcontrollerでスクレイピングの処理をかきます。

public function scrape(){

    function dbsave($url){
     //データ取得
        $crawler = Goutte::request('GET', $url);
        $crawler->filter('body')->each(function ($node) {
        $title = $node->filter('h1')->text();
        $body = $node->filter('p')->eq(0)->text();
        });
    }

    $siteurl = "https://example.com";
    dbsave($url);
}

スクレイピング後に、データの保存まで行う場合

     //データ取得
        $crawler = Goutte::request('GET', $url);
        $crawler->filter('body')->each(function ($node) {
        $title = $node->filter('h1')->text();
        $body = $node->filter('p')->eq(0)->text();
        });
        if($title != '' && $body != '' ){

     //データ保存
        $item = new Item;
        $item->name = $title;
        $item->body = $body;
        $item->save();
        }
    }

$siteurlには対象サイトのurlを指定して、データ保存の部分は各自で作成したテーブルとカラムに合わせてインスタンス名とカラム名を置き換えてください。

たとえばタイトルの取得内容を確認したいとき

$crawler = Goutte::request('GET', $url);
   $crawler->filter('body')->each(function ($node) {
   $title = $node->filter('h1')->text();
   $body = $node->filter('p')->eq(0)->text();
});
//取得できてるか確認する
dd($title);

定期実行させる

cronで定期実行させるための手順です。

コマンドクラス作成

$ php artisan make:command ScrapeCommand

定期実行させたいスクレイピングの処理を追加

app/Console/Commands/ScrapeCommand.phpを編集します。

スクレイピングの処理をhundleメソッド内にかきます。

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class TestCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    //コマンド名を設定(元:command:name→変更後:command:scrapecommand)
    protected $signature = 'command:scrapecommand';  

    /**
     * The console command description.
     *
     * @var string
     */
    //コマンドの説明(元:Command description→変更後:scrapecommandのコマンド説明)
    protected $description = 'scrapecommandのコマンド説明';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {

         // ここに処理を記述
        function dbsave($url){
     //データ取得
        $crawler = Goutte::request('GET', $url);
        $crawler->filter('body')->each(function ($node) {
        $title = $node->filter('h1')->text();
        $body = $node->filter('p')->eq(0)->text();
        });
        if($title != '' && $body != '' ){

     //データ保存
        $item = new Item;
        $item->name = $title;
        $item->body = $body;
        $item->save();
        }
        }

     $siteurl = "https://example.com";
     dbsave($url);
         
    }
}

定期実行させるためのコマンド登録

app/Console/Kernel.phpを編集します。

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{

    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        \App\Console\Commands\ScrapeCommand::class,   //コマンドの登録

    ];


    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // スケジュールの登録(「->daily()」は毎日深夜12時に実行)
        $schedule->command('command:scrapecommand')->daily();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

コマンドが登録できているか確認

$ php artisan list

コマンドを定期実行させるためにcronに登録します

$ crontab -e

* * * * * php /{path_to_project}/artisan schedule:run >> /dev/null 2>&1

cronはサーバーの管理パネルから登録することもできます。
環境によると思いますが実行間隔の指定後に

php /{path_to_project}/artisan schedule:run >> /dev/null 2>&1

と入力すると反映されると思います。

定期実行の参考サイト
https://qiita.com/miyukin1114/items/d16abc11dd4faf0e192d

以上です。