arrow_back
Back

Selenium and php-webdriver: browser automation in PHP

Andrew Dorokhov Andrew Dorokhov schedule 3 min read
menu_book Table of Contents

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:

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:

Notes:

  • Pick the Linux_x64 platform, not Linux.
  • 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

open_in_new Documentation .

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

open_in_new Documentation .

$driver->executeScript("alert('hello');");
code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward