本文目录导读:

我将为您全面介绍PHP无头浏览器测试的相关知识。
什么是无头浏览器
无头浏览器(Headless Browser)是没有图形用户界面的浏览器,它在后台运行,能执行JavaScript、处理DOM、模拟用户交互,但不需要显示界面。
主流PHP无头浏览器方案
PHPWebDriver (Facebook WebDriver)
<?php
require_once 'vendor/autoload.php';
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Chrome\ChromeOptions;
// 配置无头Chrome
$options = new ChromeOptions();
$options->addArguments([
'--headless',
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1920,1080',
'--disable-gpu'
]);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
$driver = RemoteWebDriver::create('http://localhost:9515', $capabilities);
// 访问页面
$driver->get('https://example.com');
// 执行测试
echo $driver->getTitle();
echo $driver->getCurrentURL();
// 查找元素
$element = $driver->findElement(
WebDriverBy::cssSelector('#main-content')
);
echo $element->getText();
$driver->quit();
?>
Puppeteer PHP 封装
<?php
use Nesk\Rialto\Data\JsFunction;
use Nesk\Puphpeteer\Puppeteer;
$puppeteer = new Puppeteer;
$browser = $puppeteer->launch([
'headless' => true,
'args' => ['--no-sandbox']
]);
$page = $browser->newPage();
$page->goto('https://example.com');
$page->screenshot(['path' => 'screenshot.png']);
$title = $page->title();
echo $title;
$content = $page->content();
// 执行DOM操作
$page->type('#search', 'PHP', ['delay' => 100]);
$page->click('#submit');
$browser->close();
?>
简单的cURL + DOMDocument方案
<?php
function getRenderedContent($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
]);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
// 使用DOM解析
$content = getRenderedContent('https://example.com');
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($content);
$finder = new DOMXPath($dom);
$nodes = $finder->query("//div[@class='main-content']");
?>
完整测试框架示例
PHPUnit + WebDriver 集成
<?php
use PHPUnit\Framework\TestCase;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;
class BrowserTest extends TestCase
{
private $driver;
protected function setUp(): void
{
$options = new ChromeOptions();
$options->addArguments([
'--headless',
'--no-sandbox',
'--disable-dev-shm-usage'
]);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
$this->driver = RemoteWebDriver::create(
'http://localhost:9515',
$capabilities
);
}
public function testLoginFlow()
{
$this->driver->get('https://example.com/login');
$this->driver->findElement(WebDriverBy::name('username'))
->sendKeys('testuser');
$this->driver->findElement(WebDriverBy::name('password'))
->sendKeys('testpassword');
$this->driver->findElement(WebDriverBy::cssSelector('.login-btn'))
->click();
// 等待页面跳转
$this->driver->wait(10)->until(
WebDriverExpectedCondition::urlContains('/dashboard')
);
echo $this->driver->getCurrentURL();
echo $this->driver->getTitle();
}
public function testScreenshotAndDOM()
{
$this->driver->get('https://example.com');
// 截图
$this->driver->takeScreenshot('/tmp/screenshot.png');
// 获取完整DOM
$html = $this->driver->getPageSource();
// 验证元素
$this->assertNotEmpty(
$this->driver->findElement(
WebDriverBy::cssSelector('#main-header')
)
);
}
public function testJavaScriptExecution()
{
$this->driver->get('https://example.com');
// 执行自定义JavaScript
$result = $this->driver->executeScript(
"return document.title;"
);
echo $result;
// 模拟滚动
$this->driver->executeScript(
"window.scrollTo(0, document.body.scrollHeight);"
);
sleep(2);
}
protected function tearDown(): void
{
if ($this->driver) {
$this->driver->quit();
}
}
}
?>
实用工具函数
<?php
class HeadlessBrowserHelper
{
private $driver;
public function __construct($headless = true)
{
$options = new ChromeOptions();
if ($headless) {
$options->addArguments(['--headless', '--hide-scrollbars']);
}
$options->addArguments([
'--no-sandbox',
'--disable-dev-shm-usage',
'--no-default-browser-check',
'--start-maximized'
]);
$options->addExtensions([
'/path/to/extension.crx'
]);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
$this->driver = RemoteWebDriver::create(
getenv('CHROME_DRIVER_URL') ?: 'http://localhost:9515',
$capabilities
);
}
public function getPageWithWait($url, $timeout = 10)
{
$this->driver->get($url);
$this->driver->wait($timeout)->until(
WebDriverExpectedCondition::documentReadyStateComplete()
);
return $this->driver->getPageSource();
}
public function extractData($html, $selector)
{
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$finder = new DOMXPath($dom);
return $finder->query($selector);
}
public function handleAjax($callback)
{
$driver = $this->driver;
$callback($driver);
// 等待ajax完成
$driver->wait(10)->until(function($driver) {
return $driver->executeScript(
"return jQuery.active == 0"
);
});
}
public function getNetworkRequests()
{
$requests = $this->driver->executeScript(
"return window.performance.getEntriesByType('resource')"
);
return array_map(function($request) {
return [
'url' => $request->name,
'duration' => $request->duration,
'size' => $request->transferSize
];
}, $requests);
}
public function cleanup()
{
if ($this->driver) {
$this->driver->deleteAllCookies();
$this->driver->manage()->logs()->get('browser');
$this->driver->quit();
}
}
}
?>
环境配置示例
# Dockerfile
FROM php:8.2-cli
# 安装Chrome
RUN apt-get update && apt-get install -y \
google-chrome-stable \
chromium-driver
# 安装PHP WebDriver客户端
RUN composer require php-webdriver/webdriver
# 启动ChromeDriver
CMD ["chromedriver", "--port=9515"]
# docker-compose.yml
version: '3.8'
services:
chromedriver:
image: selenium/standalone-chrome:latest
ports:
- "9515:4444"
volumes:
- /dev/shm:/dev/shm
environment:
- CHROME_HEADLESS=true
php:
build: .
depends_on:
- chromedriver
environment:
- CHROME_DRIVER_URL=http://chromedriver:4444
volumes:
- .:/var/www/html
最佳实践
等待策略
// 显式等待
$driver->wait(10)->until(
WebDriverExpectedCondition::visibilityOfElementLocated(
WebDriverBy::id('dynamic-content')
)
);
// 自定义条件
$driver->wait(10)->until(function($driver) {
return $driver->executeScript(
"return document.readyState === 'complete'"
);
});
错误处理
try {
$driver->get('https://example.com');
} catch (WebDriverException $e) {
echo "测试失败: " . $e->getMessage();
$driver->takeScreenshot('/tmp/error.png');
} finally {
$driver->quit();
}
性能优化
// 启用缓存
$driver->executeScript("localStorage.setItem('key', 'value')");
// 禁用不必要的资源
$options->addArguments(['--blink-settings=imagesEnabled=false']);
// 设置用户代理
$options->setExperimentalOption('mobileEmulation', [
'deviceName' => 'iPhone X'
]);
CI/CD集成
# GitHub Actions
name: PHP Headless Tests
on: [push, pull_request]
jobs:
headless-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, xml, curl
- name: Start ChromeDriver
run: |
google-chrome --version
chromedriver --version
- name: Run tests
run: |
composer install
php vendor/bin/phpunit --group headless
通过这些工具和技术,您可以在PHP环境中高效地进行无头浏览器测试,记住要根据具体需求选择适当的工具,并注意测试环境的稳定性和可维护性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播