PHP 初心者が WordPress の プラグイン 作成 ! part17 ( PHPからヘッドレスブラウザ操作 また失敗 )
この記事では PHP 初心者 が WordPress プラグイン を 作成 します。 part17 では再度PHPからヘッドレスブラウザを操作してみようと思います。
前回、PHPからヘッドレスブラウザを操作すべく四苦八苦しながら作業を進めました。
しかし残念ながらヘッドレスブラウザが起動せずいったん中断。
PHP 初心者が WordPress の プラグイン 作成 ! part16 ( PHPからヘッドレスブラウザ操作 失敗 )
今回は中断したところから再びスタートします。
調査
調査したところ、環境の問題のようでした。
今回プラグイン開発の環境としてDockerコンテナを使用しています。
ヘッドレスブラウザもDockerコンテナにインストールしました。
どうやらDockerからヘッドレスブラウザを動かす権利がない(?)ようです。
回避方法としてコンテナ起動時に特権モードを使用する方法やヘッドレスブラウザのオプション(–no-sandbox)を使用する方法があるようです。
特権モードはなんか怖いなぁ・・・というところがあるので–no-sandboxを付与してみようと思います。
ところでPHPではどのように指定するのか・・・。とこちらも調査してみたところありました!
しかもドンピシャ(死後)な実装です😍
<?php
require_once('./vendor/autoload.php’);
use HeadlessChromium\BrowserFactory;$browserFactory = new BrowserFactory('/usr/bin/chromium-browser’);
$options = [
'headless’ => true,
'noSandbox’ => true ,
];
$browser = $browserFactory->createBrowser($options);$page = $browser->createPage();
$page->navigate('https://www.yahoo.co.jp/’)->waitForNavigation();$pageTitle = $page->evaluate('document.title’)->getReturnValue();
echo $pageTitle, PHP_EOL;$browser->close();
実装
なるほど🤔連想配列(Map? Dictionary?)を作成しそこにnoSandboxの指定を記述するんですね。
headlessの記述も必要なのでしょうか?わからないので私もこのように指定しておきます。
$options = [
'headless' => true,
'noSandbox' => true ,
];
$browser = $browserFactory->createBrowser($options);
確認
それでは確認してみます。
http://localhost:8099/index.phpにアクセスします。
今度はうまくいきますように・・・
ガーン😫
Fatal error: Uncaught TypeError: implode(): Argument
#2 ($array) must be of type ?array, string given in /var/www/html/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php:316 Stack trace:
#0 /var/www/html/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php(316): implode(Array, '\r\n')
#1 /var/www/html/vendor/wrench/wrench/lib/Wrench/Client.php(233): Wrench\Protocol\Protocol->getRequestHandshake('ws://127.0.0.1:...', 'VqOQRduiyyM8su9...', 'http://127.0.0....', Array)
#2 /var/www/html/vendor/chrome-php/chrome/src/Communication/Socket/Wrench.php(97): Wrench\Client->connect()
#3 /var/www/html/vendor/chrome-php/chrome/src/Communication/Connection.php(156): HeadlessChromium\Communication\Socket\Wrench->connect()
#4 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(144): HeadlessChromium\Communication\Connection->connect()
#5 /var/www/html/vendor/chrome-php/chrome/src/BrowserFactory.php(73): HeadlessChromium\Browser\BrowserProcess->start('/usr/bin/chromi...', Array)
#6 /var/www/html/index.php(24): HeadlessChromium\BrowserFactory->createBrowser(Array)
#7 {main} thrown in /var/www/html/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php on line 316
またしても失敗です。今度はヘッドレスブラウザのライブラリが依存するライブラリ内でエラーが起きているようです。
英語はよくわかりませんがまだ未修正という風に見えます。
この部分だけ自分で修正できないかな?と思いこちらも調査しました。
implodeの2番目のパラメータが配列でないといけないということらしいです。
該当箇所をのぞいてみます。
/var/www/html/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php(316)
2番目のパラメータは「文字列」になっていますね。
公式サイトでもPHP8ではこの記述はできないとされています。
つまりライブラリがPHP8に対応していないということですね。
なぜPHP8にしてしまったのか・・・
2番目のパラメータは「セパレータ」を表現しているのですね。
PHP8からは「セパレータ」は1番目のパラメータに定義することになったようです。
Wrenchライブラリを修正してみる
とりあえずこう・・・直してみます。
同、ファイル内に同じ問題があったのでこちらも修正(類似問題)。
ほかにもたくさんありそうですがまずはこれだけにしておきます😦
再確認
今度はどうでしょうか。
😩
Fatal error: Uncaught HeadlessChromium\Exception\OperationTimedOut: Operation timed out (5sec) in /var/www/html/vendor/chrome-php/chrome/src/Utils.php:69 Stack trace:
#0 /var/www/html/vendor/chrome-php/chrome/src/Communication/ResponseReader.php(108): HeadlessChromium\Utils::tryWithTimeout(5000000, Object(Generator))
#1 /var/www/html/vendor/chrome-php/chrome/src/Communication/Session.php(84): HeadlessChromium\Communication\ResponseReader->waitForResponse(5000)
#2 /var/www/html/vendor/chrome-php/chrome/src/Browser.php(170): HeadlessChromium\Communication\Session->sendMessageSync(Object(HeadlessChromium\Communication\Message))
#3 /var/www/html/index.php(27): HeadlessChromium\Browser->createPage()
#4 {main} thrown in /var/www/html/vendor/chrome-php/chrome/src/Utils.php on line 69
まとめ
PHPからヘッドレスブラウザ操作に再挑戦しました。
またしても失敗でしたが着実に進んでいるように感じます。
次はうまくいきそうな予感です(笑
index.phpの全体像は以下のようになりました。
<?php
// $a = 1;
// if ($a === 1) {
// echo "ほげ";
// } else {
// echo "fuga";
// }
// autoloadを読み込む
require 'vendor/autoload.php';
use HeadlessChromium\BrowserFactory;
// whereis chromiumでパスを探した
$browserFactory = new BrowserFactory('/usr/bin/chromium');
// for Docker option
$options = [
'headless' => true,
'noSandbox' => true ,
];
// starts headless chrome
$browser = $browserFactory->createBrowser($options);
// creates a new page and navigate to an url
$page = $browser->createPage();
$page->navigate('https://www.google.co.jp')->waitForNavigation();
// get page title
$pageTitle = $page->evaluate('document.title')->getReturnValue();
// screenshot
$page->screenshot()->saveToFile('/var/www/html/bar.png');
// pdf
$page->pdf(['printBackground'=>false])->saveToFile('/var/www/html/bar.pdf');
// bye
$browser->close();
?>
今日はここまで!
ディスカッション
コメント一覧
まだ、コメントがありません