数年前まではRubyやPython、Node.jsなどを使用するか、もしくはPHPのGoutteを使用する場合が多かったブラウザの自動操作ですが、
Facebookの作ったライブラリ「facebook/php-webdriver」を使用すると、PHPでも簡単にブラウザの自動操作が行えます。
そんな便利なライブラリですが、(執筆時では)
- ヘッドレスモードではファイルダウンロードが行えない
- ChromeDriver::start()ではタイムアウト値が固定されている
という問題点があるため、カスタマイズしてもっと便利にしてみました。
注意事項
以下、早速の注意事項で申し訳ありません。
- composerでインストールしたソースを直接改修するため、リスクがあります。
- 本記事の内容は、2019年4月4日(木)にカスタマイズ及び動作確認を行った内容です。
使用するライブラリ、ブラウザ、ドライバー
繰り返しになりますが、使用するライブラリは以下です。
composerでインストールしてご使用ください。(動作確認したバージョンは1.6.0です)
GitHub – facebook/php-webdriver: A php client for webdriver.
https://github.com/facebook/php-webdriver
また、ブラウザはGoogle Chromeを使用します。
インストールされていない場合はインストールをお願いします。
1 2 3 4 5 6 | # curl https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - # echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list # apt update # apt install google-chrome-stable # google-chrome-stable --version Google Chrome 73.0.3683.103 |
Chromeブラウザを操作するために、以下からChromeドライバーをダウンロードして使用します。
(動作確認したものは、Linux x64のバージョン73.0.3683.68です)
Downloads – ChromeDriver – WebDriver for Chrome
http://chromedriver.chromium.org/downloads
ヘッドレスモードでダウンロードが行えない対策
ブラウザをGUIで起動して使用する分にはファイルのダウンロードは問題なく行えますが、
ヘッドレスモードで使用する場合はファイルのダウンロードが行えない問題があります。
Linuxなどのサーバー上で使用する場合はヘッドレスモードがほぼ必須になること、
またCSVファイル等のダウンロードが行えないため、ダウンロードできるようにカスタマイズします。
以下、カスタマイズ内容です。
カスタマイズ内容
vendor/facebook/webdriver/lib/Remote/DriverCommand.php
の差分情報。
差分(テキスト版)
1 2 3 4 5 6 7 8 9 | // Mobile API const GET_NETWORK_CONNECTION = 'getNetworkConnection'; const SET_NETWORK_CONNECTION = 'setNetworkConnection'; + + // my add + const CHROMIUM_SEND_COMMAD = 'chromiumSendCommand'; private function __construct() { |
差分(画像版)
vendor/facebook/webdriver/lib/Remote/HttpCommandExecutor.php
の差分情報。
差分(テキスト版)
1 2 3 4 5 6 7 8 9 | DriverCommand::TOUCH_MOVE => ['method' => 'POST', 'url' => '/session/:sessionId/touch/move'], DriverCommand::TOUCH_SCROLL => ['method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'], DriverCommand::TOUCH_UP => ['method' => 'POST', 'url' => '/session/:sessionId/touch/up'], + + // my add + DriverCommand::CHROMIUM_SEND_COMMAD => ['method' => 'POST', 'url' => '/session/:sessionId/chromium/send_command'], ]; /** * @var string |
差分(画像版)
カスタマイズ後の使用例
インポートするもの
1 2 3 4 5 6 7 8 9 10 11 | // facebook/php-webdriver use Facebook\WebDriver; use Facebook\WebDriver\WebDriverExpectedCondition; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Chrome\ChromeDriver; use Facebook\WebDriver\Remote; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\WebDriverKeys; use Facebook\WebDriver\WebDriverSelect; |
ダウンロードディレクトリを設定する関数
1 2 3 4 5 6 7 8 9 10 11 12 | public function setDownloadDir($driver, $path) { try { $driver->execute(Remote\DriverCommand::CHROMIUM_SEND_COMMAD, [ 'cmd' => 'Page.setDownloadBehavior', 'params' => ['behavior' => 'allow', 'downloadPath' => $path], ]); } catch (\Exception $e) { \Log::error($e->getMessage()); } } |
ブラウザをヘッドレスモード+ダウンロードディレクトリを設定して起動
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // chromedriverのパスを指定 $driverPath = 'chromedriver'; putenv('webdriver.chrome.driver=' . $driverPath); // オプション $options = new ChromeOptions(); // Chromeを起動するときのオプション指定用 $options->addArguments([ '--no-sandbox', '--headless', // ヘッドレスで起動するように指定。ダウンロードフォルダ指定が無効になる。 '--disable-gpu', // ヘッドレスで暫定的に必要なフラグ '--ignore-certificate-errors', // SSLセキュリティ証明書のエラーページ(「このサイトのセキュリティ証明書は信頼できません」のページ)を表示しません。 ]); // Chromeブラウザを起動 $caps = DesiredCapabilities::chrome(); $caps->setCapability(ChromeOptions::CAPABILITY, $options); $driver = ChromeDriver::start($caps); // ダウンロードディレクトリを設定(ヘッドレスモードでダウンロード処理が行えない対策) $path = '/tmp/'; // ダウンロードディレクトリのパス $this->setDownloadDir($driver, $path) // 画面サイズを最大化 $driver->manage()->window()->maximize(); // 〜処理〜 // ブラウザ終了 $driver->quit(); |
最後に
以上のカスタマイズにより、ブラウザ操作の中で以下のようなファイルダウンロードのリンクやボタンをクリックすると、指定したディレクトリにファイルがダウンロードされるようになりました。
1 | $driver->findElement(WebDriverBy::id('form_submit'))->click(); |
なお、本カスタマイズ内容は以下のサイトを参考にさせて頂きました。(内容ほぼそのままです)
大変ありがとうございます。
【参考サイト】
PHPでChromeを操作(ダウンロードフォルダ指定)|743|note
https://note.mu/743/n/n2c1c07062f7f
ChromeDriver::start()では、タイムアウト設定ができない為タイムアウトが設定できるように対処
ChromeDriver::start()では、コネクションタイムアウト/リクエストタイムアウトのデフォルト値は30秒程しかないため、それ以上かかってしまった場合は処理が中断されてしまう問題があります。
普通に使用する場合は30秒もあれば十分ですが、例えばCSVファイルをダウンロード時に、サイト側でCSVファイルを生成してからダウンロードが開始されるため、リクエストタイムアウトの30秒を超えてしまう場合があります。
このような問題回避のため、タイムアウト値を自由に設定できるようカスタマイズを行います。
以下、カスタマイズ内容です。
カスタマイズ内容
vendor/facebook/webdriver/lib/Chrome/ChromeDriver.php
の差分情報。
差分(テキスト版)
・30行目
1 2 3 4 5 6 7 8 | /** * @return static */ - public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null) + public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null, $connection_timeout_in_ms = null, $request_timeout_in_ms = null) { if ($desired_capabilities === null) { $desired_capabilities = DesiredCapabilities::chrome(); |
・39〜44行目
1 2 3 4 5 6 7 8 9 10 11 | $service = ChromeDriverService::createDefaultService(); } $executor = new DriverCommandExecutor($service); + if ($connection_timeout_in_ms !== null) { + $executor->setConnectionTimeout($connection_timeout_in_ms); + } + if ($request_timeout_in_ms !== null) { + $executor->setRequestTimeout($request_timeout_in_ms); + } $driver = new static($executor, null, $desired_capabilities); $driver->startSession($desired_capabilities); |
差分(画像版)
カスタマイズ後の使用例
1 2 3 | - $driver = ChromeDriver::start($caps); + // コネクションタイムアウト:5分、リクエストタイムアウトを10分に変更する場合 + $driver = ChromeDriver::start($caps, null, 1000*60*5, 1000*60*10); |
最後に
以上のカスタマイズにより、ChromeDriver::start()でもタイムアウト値が自由に設定できるようになりました。
ファイルダウンロード処理を伴う場合は、恐らくタイムアウト値を大きくすることが必須になりそうです。
最後に
以上、facebook/php-webdriverのカスタマイズ方法でした。
composerでインストールしたソースに手を加えるためリスクが伴いますが、どうしてもPHPでブラウザ操作を行いたくて、ファイルダウンロードやタイムアウト値を変更したい場合は参考になれば幸いです。
composerでインストールしたソースに手を加えるため、Gitでのバージョン管理やデプロイ時、ライブラリのバージョンアップには注意が必要ですね。
facebook/php-webdriverでは、他にもUser Agentの設定やプロキシの設定、Chrome拡張機能(エクステンション)を読み込むこともできます。
特にChrome拡張機能は使い方次第では面白いことが出来そうです。
もしブラウザ自動操作をする上で、読み込ませたほうが良い便利な拡張機能があれば情報お待ちしてます。
【動確環境】
OS:Ubuntu 18.04.2 LTS
facebook/webdriver:1.6.0
google-chrome-stable:73.0.3683.103
ChromeDriver:73.0.3683.68(Linux x64)
コメントを残す