Debian + PHPを使ってプログラム経由でWEBページにアクセスする (Chrome+facebook/webdriver)
Debian + PHPを使ってプログラム経由でWEBページにアクセスする (Chrome+facebook/webdriver)方法は以下の通り
目次
DebianにChromeをインストールする
DebianにChromeをインストールする方法は以下のページを参照
[bitnami] DebianにChromeをインストールする方法
chromedriverをダウンロード
https://chromedriver.chromium.org/downloads
上記サイトからChromeのバージョンにあったchromedriverをダウンロードして
/usr/local/bin/chromedriver
に配置
chmod +x /usr/local/bin/chromedriver
で属性変更
Composerをインストール
下記ページを参照してComposerをインストール
対象フォルダにcomposer.pharとcomposer.jsonができていることを確認
facebook/webdriver とsymfony/processをcomposerでインストール
composer.jsonに下記のようにphp-webdriver/webdriverを記述する
{
“require”: {
“php-webdriver/webdriver”:”*”
}
}
***下記削除項目:facebook/webdriverは提供終了となった
facebook/webdriver とsymfony/processをインストールするように書く。facebook/webdriverにはsymfony/processが必要
{ "require": { "facebook/webdriver" : "^1.7", "symfony/process": "^2.8" } }
php composer.phar installを実行してインストール
php composer.phar install もしくは composer update
vendorフォルダができていることを確認
PHPでWEBサイトのスクリーンショットを録り、pngで保存するプログラム
require_once ( __DIR__ . '/../vendor/autoload.php'); use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Chrome\ChromeDriver; use Facebook\WebDriver\Chrome\ChromeOptions; $file_path = __DIR__ . '/tmp/ss.png'; $url = "https://www.yahoo.co.jp"; $driverPath = realpath("/usr/local/bin/chromedriver"); putenv("webdriver.chrome.driver=" . $driverPath); // Chromeを起動 $options = new ChromeOptions(); $options->addArguments(['--headless']); $options->addArguments(['--no-sandbox']); $options->addArguments(['--disable-gpu']); $options->addArguments(["--lang=ja"]); $caps = DesiredCapabilities::chrome(); $caps->setCapability(ChromeOptions::CAPABILITY, $options); $driver = ChromeDriver::start($caps); //画面を取得 $driver->get($url); // スクリーンショットを保存 sleep(3); $driver->takeScreenshot($file_path); // ブラウザを閉じる $driver->quit();
Yahooのページのスクリーンショットを取得し、tmpフォルダにssというpngを書き込むようになっている。tmpフォルダは書き込みできるようにしておくこと。
上記プログラムでは
‘Facebook\WebDriver\ChromeOptions’ not found”.
というエラーは出ない
メモ
当初chrome-php/chromeを使用しようとしたのだが、なぜかPermission Errorが出るので、上記facebook/webdriverの方法を採用した。
さらにメモ
上記コードが開発環境で動いたので、本番環境に移植したところchromeが正常に起動しないエラーが発生した
Got error 'PHP message: PHP Fatal error: Uncaught Facebook\\WebDriver\\Exception\\UnknownErrorException: unknown error: Chrome failed to start: exited abnormally.\n (unknown error: DevToolsActivePort file doesn't exist)\n (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) in
「DevToolsActivePort file doesn’t exist」は適切なChrome Optionをつけていないため「–headless」をつければよいとか「–disable-dev-shm-usage」をつければよいとか「disable-infobars」をつければよいなどの情報がインターネット上にあったものの、すべてNG。原因不明。わからん。
また上記エラーにてChromeがクラッシュしているため、ChromeDriverがプロセス上に残っている。そのため上記エラーが発生してから再度プログラムを起動させると
Got error 'PHP message: PHP Fatal error: Uncaught Exception: Error starting driver executable "'/usr/local/bin/chromedriver' '--port=9515'": [1615908020.909][SEVERE]: bind() failed: Address already in use (98)\n in
のエラーに変化する。要するに既にポート使っているよ、という状態なので、一度ChromeDriverのプロセスをKillしてあげる必要がある
sudo killall chromedriver
でKillできる。
回避:ChromeDriver::startを使用しない
ChromeDriver::startでエラーが起きているため、ChromeDriver::startを使用しないプログラムに変更した
ChromeDriverの公式ページでは、予めローカルでChromeDriverを起動させておき、そのChromeにアクセスしてページ情報を取得する方法も書かれている
nohup chromedriver --port=4444 &
nohupを使用してバックグラウンドでchromedriverをPort4444で起動。これでターミナルを閉じてもChromeDriverは停止しない。
さらにPHPプログラムを
$serverUrl = 'http://localhost:4444'; $driver = RemoteWebDriver::create($serverUrl, $caps); //$driver = ChromeDriver::start($caps);
とRemoteWebDriver::createを使用する。
これで、先程起動させたChromeDriverを使用してクローリングできる。