WebDriver (Selenium WebDriver) is a browser driver — a headless software library that lets other programs interact with a browser: control its behavior, read data from it, and issue commands to it.
WebDriver became a standard: open_in_new https://www.w3.org/TR/webdriver1/ . So Selenium WebDriver isn’t really a single tool — it’s a specification describing the interface browsers must expose so that something else can drive them.
Homepage: open_in_new https://www.selenium.dev .
PHP client library: open_in_new php-webdriver .
API documentation: open_in_new https://php-webdriver.github.io/php-webdriver/latest/ .
Docs:
- open_in_new Webdriver PHP API walkthrough
- open_in_new Bot detection tool , useful for checking whether your automated browser looks like a bot.
Installation and avoiding detection
First, install the driver you’ll control through the API — it launches the actual browser and executes your commands. Options:
- Selenium standalone server.
- Chromedriver (for Chrome).
- Geckodriver (for Firefox).
The last two implement the Selenium WebDriver standard, so they work fine with open_in_new any client library , not just php-webdriver.
ChromeDriver
Download it open_in_new here . The driver version must match the installed Chrome/Chromium version.
Avoiding bot detection
Sites can detect a WebDriver session through the navigator.webdriver property. It can be removed on the driver side:
// C#
var options = new ChromeOptions();
options.AddExcludedArguments(new List<string>() { "enable-automation" });
# Python
options.add_experimental_option("excludeSwitches", ['enable-automation'])
This trick only works with ChromeDriver 79.0.3945.16 and earlier. For example, with Chrome 78.0.3904.97 you’d pair it with chromedriver 78.0.3904.10500:
- open_in_new Download ChromeDriver 78.0.3904.105
- open_in_new Download the matching Chromium build (open_in_new all versions )
- open_in_new How to find the right Chromium build
Notes:
- Pick the
Linux_x64platform, notLinux. - ChromeDriver can live in the same directory as Chromium — no need to look for it separately.
There’s also a open_in_new dedicated test for headless-browser detection if you need to check whether headless mode itself is being fingerprinted.
Configuring RemoteWebDriver
The core of it:
use Facebook\WebDriver\Remote\RemoteWebDriver;
$driver = RemoteWebDriver::create('http://localhost:4444', $browser_caps);
$driver->get('https://www.whitepages.com/');
Choosing browser capabilities:
$browser_caps = DesiredCapabilities::chrome();
$browser_caps = DesiredCapabilities::firefox();
$browser_caps = DesiredCapabilities::microsoftEdge();
Chrome options
$options = new ChromeOptions();
// Hide the "controlled by automated software" notice:
$options->setExperimentalOption('excludeSwitches', ['enable-automation']);
$browser_caps = DesiredCapabilities::chrome();
$browser_caps->setCapability(ChromeOptions::CAPABILITY, $options);
Chrome command-line arguments
$options = new ChromeOptions();
// Window size:
$options->addArguments(['window-size=1024,768']);
// Headless mode:
$options->addArguments(['headless']);
Page operations
Navigate to a URL:
$driver->get('https://en.wikipedia.org/wiki/Selenium_(software)');
Get the current URL:
$driver->getCurrentURL();
Get the page source (the initial HTML from the server, not the rendered DOM):
$page_source = $driver->getPageSource();
Get the page title:
$title = $driver->getTitle();
Finding elements
Build a locator with WebDriverBy:
// CSS selector:
WebDriverBy::cssSelector('h1.foo > small');
// XPath:
WebDriverBy::xpath('(//hr)[1]/following-sibling::div[2]');
// ID:
WebDriverBy::id('heading');
// Class name:
WebDriverBy::className('warning');
// Name attribute (on inputs):
WebDriverBy::name('email');
// Tag name:
WebDriverBy::tagName('h1');
// Link text:
WebDriverBy::linkText('Sign in here');
// Partial link text:
WebDriverBy::partialLinkText('Sign in');
Find an element (returns a RemoteWebElement):
$element = $driver->findElement(WebDriverBy::name('search'));
Actions with elements
Get text:
$element->getText();
Get an attribute:
$element->getAttribute('id');
Trigger a mouseover (hover):
$element = $driver->findElement(WebDriverBy::id('some_id'));
$driver->getMouse()->mouseMove($element->getCoordinates());
Click:
$driver->findElement(WebDriverBy::id('signin'))->click();
Executing JavaScript
$driver->executeScript("alert('hello');");
Andrew Dorokhov