PHPでChromeを操作(クロール)
滅多に環境構築しないので、やった事などをメモ。
目的
PHP & facebook-webdriver & ChromeDriver & Chrome もしくは
PHP & facebook-webdriver & Selenium & ChromeDriver & Chrome で
クロール環境を構築。
環境
CentOS 7でPHP 5.6が動作する状態。
Google Chromeのインストール
sudo yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
最新版がインストールされるのでChromeDriverを利用する場合はバージョンを確認。
google-chrome --version
日本語フォントのインストール
sudo yum install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
Chrome の動作確認
google-chrome --headless --disable-gpu --dump-dom http://example.com/
PDFで保存する場合は --dump-dom の代わりに --print-to-pdf を追加。
rootの場合は --no-sandbox を追加しないとエラーになる。
最近のバージョンで --disable-gpu が必要なのはWindowsだけらしい。
WebGLを無効にするには --disable-software-rasterizer も必要らしいけどよく判らない。
[0525/145839.044162:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.
エラーが出てるけど動作してるのでとりあえず放置。
PATHの確認
echo $PATH
composerとかをインストールするディレクトリを確認。
composerのインストール
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin
sudo chown root:root /usr/local/bin/composer.phar
インストールが終わったらバージョン確認。
composer.phar -V
facebook-webdriverのインストール
PHPのプロジェクトのディレクトリに移動。
php composer.phar require facebook/webdriver
パスが通ってるはずなのにcomposer.pharがオープンエラー。
php /usr/local/bin/composer.phar require facebook/webdriver
解決方法が分からないのでフルパスで指定。
Do not run Composer as root/super user! See https://getcomposer.org/root for details
rootの場合にwarningが出るけど処理は続行するので放置。
ChromeDriver 2.38とライブラリのインストール(Seleniumの場合も必要)
http://chromedriver.chromium.org/downloads
最新版を確認。(2018/05/18の時点でバージョン2.38)
wget https://chromedriver.storage.googleapis.com/2.38/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin
sudo chown root:root /usr/local/bin/chromedriver
sudo yum install -y libX11 GConf2 fontconfig
インストールが終わったらバージョン確認。
chromedriver -v
PHPから利用する場合に /usr/local/bin/chromedriver を指定する。
Selenium 3.9のインストール(ChromeDriverの場合は不要)
http://selenium-release.storage.googleapis.com/index.html
最新版を確認。(2018/05/18の時点でバージョン3.9.1)
wget https://selenium-release.storage.googleapis.com/3.9/selenium-server-standalone-3.9.1.jar
sudo mv selenium-server-standalone-3.9.1.jar /usr/local/bin
sudo chown root:root /usr/local/bin/selenium-server-standalone-3.9.1.jar
Java 8 (JDK) ランタイムのインストール
yum search java-1.8.0-openjdk
yum install java-1.8.0-openjdk
ChromeDriverの場合やインストール済みの場合は不要。
Seleniumの起動
java -jar selenium-server-standalone-3.9.1.jar
パス通ってるのにエラー。
java -jar /usr/local/bin/selenium-server-standalone-3.9.1.jar
解決方法が分からないのでフルパスで指定。
INFO - Selenium Server is up and running on port 4444
動作が確認できたら「Ctrl + C」で終了。
Seleniumの常駐起動
java -jar /usr/local/bin/selenium-server-standalone-3.9.1.jar &
終了する場合は「ps -ef」で探して「kill (PIDを指定)」で終了。
ソース(test.php)
<?php
require_once(__DIR__ . '/vendor/autoload.php');
use Facebook\WebDriver\Chrome\ChromeDriver;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Exception\WebDriverException;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\RemoteWebElement;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;
// ChromeDriver & facebook-webdriver
function testChromeDriver()
{
$width = 400;
$height = 400;
// 環境変数
putenv('webdriver.chrome.driver=/usr/local/bin/chromedriver');
try
{
// 非表示設定で起動
$option = new ChromeOptions();
$option->addArguments([
// '--no-sandbox', // rootの場合に必須
'--headless',
'--disable-gpu',
('--window-size=' . $width . ',' . $height), // 非表示でもスクリーンショットのサイズに反映
]);
$chrome = DesiredCapabilities::chrome();
$chrome->setCapability(ChromeOptions::CAPABILITY, $option);
$driver = ChromeDriver::start($chrome);
// デフォルト設定で起動
// $driver = ChromeDriver::start();
// googleに移動
$driver->get('https://www.google.co.jp/');
// <input id="lst-ib" > に対して 'ChromeDriverでクロール' を入力して検索
$driver->findElement(WebDriverBy::id('lst-ib'))->sendKeys('ChromeDriverでクロール')->submit();
// タイムアウト10秒でタイトルを監視
$driver->wait(10)->until(
WebDriverExpectedCondition::titleIs('ChromeDriverでクロール - Google 検索')
);
// タイトルを確認
if ($driver->getTitle() === 'ChromeDriverでクロール - Google 検索')
{
// スクリーンショット
$driver->takeScreenshot(__DIR__ . '/' . __METHOD__ . '_' . __LINE__ . '.png');
}
// 終了
$driver->quit();
}
catch (Exception $e)
{
var_dump($e);
}
}
// Selenium & facebook-webdriver
function testSelenium()
{
$width = 400;
$height = 400;
$selenium = 'http://localhost:4444/wd/hub';
try
{
// 非表示設定で起動
$option = new ChromeOptions();
$option->addArguments([
// '--no-sandbox', // rootの場合に必須
'--headless',
'--disable-gpu',
('--window-size=' . $width . ',' . $height), // 非表示でもスクリーンショットのサイズに反映
]);
$chrome = DesiredCapabilities::chrome();
$chrome->setCapability(ChromeOptions::CAPABILITY, $option);
$driver = RemoteWebDriver::create($selenium, $chrome);
// デフォルト設定で起動
// $driver = RemoteWebDriver::create($selenium, DesiredCapabilities::chrome());
// googleに移動
$driver->get('https://www.google.co.jp/');
// <input id="lst-ib" > に対して 'Seleniumでクロール' を入力して検索
$driver->findElement(WebDriverBy::id('lst-ib'))->sendKeys('Seleniumでクロール')->submit();
// タイムアウト10秒でタイトルを監視
$driver->wait(10)->until(
WebDriverExpectedCondition::titleIs('Seleniumでクロール - Google 検索')
);
// タイトルを確認
if ($driver->getTitle() === 'Seleniumでクロール - Google 検索')
{
// スクリーンショット
$driver->takeScreenshot(__DIR__ . '/' . __METHOD__ . '_' . __LINE__ . '.png');
}
// 終了、close()だとセッションが残る
$driver->quit();
}
catch (Exception $e)
{
var_dump($e);
}
}
// 実行
testChromeDriver();
// 実行
testSelenium();
vendorフォルダと同じ階層にtest.phpで保存。
Windowsで編集する場合に文字コードが間違ってるとsendKeys()でエラーになる。
PHP実行
php test.php
ソースと同じ場所に画像が2枚作成されていれば成功。
パーミッション次第では画像が作成できないので注意。
Failed connect to localhost:4444; Connection refused' in /作業ディレクトリ/vendor/facebook/webdriver/lib/Remote/HttpCommandExecutor.php:292
Seleniumを起動していないとエラーになるのでChromeDriverの方が良さそう。