PHPでChromeを操作(ダウンロードフォルダ指定)

Chromeの通常モードとヘッドレスモードで挙動が違うのでハマった。

PHP (bug code)

$option = new ChromeOptions();
$option->addArguments([
		'--no-sandbox',
		'--headless',    // ダウンロードフォルダ指定が無効になる
		'--disable-gpu',
	]);
// ダウンロードフォルダ指定
$option->setExperimentalOption('prefs', [
		'download.prompt_for_download' => false,
		'download.default_directory'   => $path,
	]);

--headlessオプション付けると一部のオプションが無効になるらしい。
ヘッドレスモードの場合は起動してからjsonをPOSTする必要があるのにWebDriverが非対応だった。

ChromeのPOST URL

http://localhost:9515/session/:sessionId/chromium/send_command

ソース確認したらポートは9515でハードコーディングしてあった。
:sessionIdはRemoteWebDriver::getSessionID()で取得した値。

SeleniumのPOST URL

http://localhost:4444/wd/hub/session/:sessionId/chromium/send_command

Seleniumデフォルト起動なら4444ポート。
:sessionIdはRemoteWebDriver::getSessionID()で取得した値。

json

{
    "cmd": "Page.setDownloadBehavior",
    "params": {
        "behavior": "allow",
        "downloadPath": "$path"
    }
}

$pathはダウンロードフォルダ。

自前でPOST処理を実装するかWebDriverにパッチ当てるかの2択。
面倒なのでリスクを承知の上でWebDriverにパッチ。

/vendor/facebook/webdriver/lib/Remote/HttpCommandExecutor.php

'chromiumSendCommand' => [ 'method' => 'POST', 'url' => '/session/:sessionId/chromium/send_command' ],

$commands配列に追加。
面倒なのでDriverCommand.phpは未修正。

PHP

public function setDownloadDir($driver, $path)
{
	$ret = false;

	try
	{
		$ret = $driver->execute('chromiumSendCommand', [
				'cmd'    => 'Page.setDownloadBehavior',
				'params' => [ 'behavior' => 'allow', 'downloadPath' => $path ],
			]);
	}
	catch (Exception $e)
	{
		var_dump($e->getMessage());
	}

	return $ret;
}

'chromiumSendCommand'はHttpCommandExecutor.phpの$commands配列のkeyを指定。
本来はDriverCommand::xxxxになるけどDriverCommand.phpが未修正なので文字列で指定。



この記事が気に入ったらサポートをしてみませんか?