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を使用してクローリングできる。