I am trying to fill a web form to send SMS using php-webdriver on a site that uses recaptcha v2. My PHP script also start Selenium standalone server from bat files: selenium-server-hub.bat and selenium-server-node.bat.
selenium-server-hub.bat
chcp 65001
chdir C:inetpubwwwrootmedserviceswwwrootseleniumserver
"C:Program FilesJavajdk-24binjava.exe" -jar "selenium-server-4.35.0.jar" hub
selenium-server-node.bat
chcp 65001
chdir C:inetpubwwwrootmedserviceswwwrootseleniumserver
"C:Program FilesJavajdk-24binjava.exe" -Dwebdriver.edge.driver=msedgedriver.exe -jar "selenium-server-4.35.0.jar" node --config "NodeWebDriver.json"
NodeWebDriver.json
{
"capabilities": [
{
"browserName": "MicrosoftEdge",
"maxInstances": 5,
"seleniumProtocol": "WebDriver",
"platform": "WINDOWS"
},
{
"browserName": "firefox",
"maxInstances": 5,
"seleniumProtocol": "WebDriver",
"platform": "WINDOWS"
},
{
"browserName": "chrome",
"maxInstances": 5,
"seleniumProtocol": "WebDriver",
"platform": "WINDOWS"
},
{
"browserName": "internet explorer",
"maxInstances": 1,
"seleniumProtocol": "WebDriver",
"platform": "WINDOWS"
}
],
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"maxSession": 5,
"port": 5555,
"register": true,
"registerCycle": 5000,
"hub": "http://Администратор:[email protected]:4444",
"nodeStatusCheckTimeout": 5000,
"nodePolling": 5000,
"role": "node",
"unregisterIfStillDownAfter": 60000,
"downPollingLimit": 2,
"debug": false,
"servlets": [],
"withoutServlets": [],
"custom": {}
}
PHP script, which fills a web form and attempts to pass recaptcha
<?php
require_once "C:\Program Files\IIS Express\PHP\v8.3\lib\php-webdriver\vendor\autoload.php";
use FacebookWebDriverRemoteRemoteWebDriver;
use FacebookWebDriverRemoteDesiredCapabilities;
use FacebookWebDriverWebDriverBy;
function CheckIfSeleniumServerStarted(string $role) : bool
{
$isStarted = false;
$handle = curl_init();
if($handle instanceof CurlHandle)
{
curl_setopt_array($handle,
[
CURLOPT_URL => $role === "node" ? "http://Администратор:7565@localhost:5555" : "http://Администратор:7565@localhost:4444",
CURLOPT_HTTPHEADER => [ "Connection: keep-alive", "Accept: */*" ],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 60,
CURLOPT_TIMEOUT => 60,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => $_SERVER["HTTP_USER_AGENT"],
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_SSL_VERIFYPEER => FALSE
]);
$result = curl_exec($handle);
$isStarted = is_string($result) && ($statusCode = curl_getinfo($handle, CURLINFO_HTTP_CODE)) >= 200 && $statusCode < 300;
curl_close($handle);
}
return $isStarted;
}
ini_set("display_errors", true);
header('Content-Type: text/html; charset=utf-8');
$log_filename = str_replace("php", "log", __FILE__);
$log_handle = fopen($log_filename, "w+");
if($log_handle !== false)
{
set_error_handler(fn(int $errno, string $errstr, string $errfile = null, int $errline = 0) =>
error_log("Error: {$errno} in {$errfile}, line no {$errline}n{$errstr}", 3, $log_filename), E_ALL);
}
// Start Selenium server
$cmdPath = "C:\Windows\system32\cmd.exe";
$workingDir = __DIR__ . "\selenium\server";
$shell = null;
if(!CheckIfSeleniumServerStarted("hub"))
{
$command = "{$cmdPath} /C {$workingDir}\selenium-server-hub.bat 2>&1 &";
$shell = new COM("WScript.Shell");
$shell->Run($command, 1, false);
sleep(1);
}
if(!CheckIfSeleniumServerStarted("node"))
{
$command = "{$cmdPath} /C {$workingDir}\selenium-server-node.bat 2>&1 &";
$shell = $shell ?? new COM("WScript.Shell");
$shell->Run($command, 1, false);
sleep(1);
}
$classRemoteWebDriver = "\Facebook\WebDriver\Remote\RemoteWebDriver";
$classRemoteWebElement = "\Facebook\WebDriver\Remote\RemoteWebElement";
$pageHtml = "";
$edgeOptions = ["args" => [ "--ignore-certificate-errors"]];
$capabilities = DesiredCapabilities::microsoftEdge();
$capabilities->setCapability("ms:edgeOptions", $edgeOptions);
$host = "http://localhost:4444";
$webDriver = RemoteWebDriver::create($host, $capabilities);
if($webDriver instanceof $classRemoteWebDriver)
{
$webDriver->get("https://bomgovka.ru");
$elemNumber = $webDriver->findElement(WebDriverBy::xpath("//input[@id='number']"));
$elemMessage = $webDriver->findElement(WebDriverBy::xpath("//textarea[@id='message']"));
if($elemNumber instanceof $classRemoteWebElement && $elemMessage instanceof $classRemoteWebElement)
{
$phoneNumber = "XXXXXXXXXXX";
$elemNumber->sendKeys($phoneNumber);
sleep(3);
$elemMessage->sendKeys("Test message");
sleep(3);
$element = $webDriver->findElement(WebDriverBy::xpath("//iframe[starts-with(@name, 'a-') and starts-with(@src, 'https://www.google.com/recaptcha')]"));
error_log("Recaptcha iframe is " . ($element instanceof $classRemoteWebElement ? "found" : "not found"), 3, $log_filename);
if($element instanceof $classRemoteWebElement)
{
$webDriver = $webDriver->switchTo()->frame($element);
error_log("Switch to recaptcha iframe is " . (!($webDriver instanceof $classRemoteWebDriver) ? "not " : "") . "completed.", 3, $log_filename);
if($webDriver instanceof $classRemoteWebDriver)
{
$element = $webDriver->wait(25)->until(FacebookWebDriverWebDriverExpectedCondition::elementToBeClickable(WebDriverBy::xpath("//div[@class = 'recaptcha-checkbox-border']")));
error_log("Recaptcha checkbox is " . ($element instanceof $classRemoteWebElement ? "found and clickable" : "not found or not clickable"), 3, $log_filename);
if($element instanceof $classRemoteWebElement)
{
$element->click();
$pageHtml = $webDriver->getPageSource();
$webDriver = $webDriver->switchTo()->defaultContent();
error_log("Switch to default content is " . (!($webDriver instanceof $classRemoteWebDriver) ? "not " : "") . "completed.", 3, $log_filename);
if($webDriver instanceof $classRemoteWebDriver)
{
$elemButton = $webDriver->wait(25)->until(FacebookWebDriverWebDriverExpectedCondition::elementToBeClickable(WebDriverBy::xpath("//input[@name='contact-submit']")));
error_log("Submit button is " . ($elemButton instanceof $classRemoteWebElement ? "found and clickable." : "not found or not clickable."), 3, $log_filename);
if($elemButton instanceof $classRemoteWebElement)
{
$elemButton->click();
sleep(3);
$pageHtml = $webDriver->getPageSource();
}
}
}
}
}
}
$webDriver->quit();
}
echo $pageHtml;
if(is_resource($log_handle))
{
fclose($log_handle);
}
?>
But as a result of the script executing, recaptcha is not passed and site returns “Error. Please pass the ‘I’m not a robot’ check”.
How to pass recaptcha using php-webdriver correctly or it’s impossible using only php-webdriver?