如何使用PHP和Selenium快速构建自己的网络爬虫系统

近年来,随着互联网的普及,网络爬虫逐渐成为了信息采集的主要手段之一,然而,常规的爬虫技术不稳定、难以维护,市面上的纯web网页爬虫也只能在静态页面上进行操作。而php结合selenium可达到动态爬虫的效果,具有稳定性高、数据采集全面等优点,被广泛应用于爬虫开发中。本文将介绍如何使用php和selenium快速构建自己的网络爬虫系统。

一、Selenium和ChromeDriver的安装

Selenium是一个自动化测试工具,可以对Web应用程序进行自动化测试,其中将浏览器与操作系统分离式地处理,无强制插入代码实现页面渲染。ChromeDriver则是Selenium中调用Chrome浏览器的驱动程序,可以使Selenium直接操作Chrome,从而实现动态页面的爬取。

首先需要在本地安装Chrome浏览器和PHP环境。接着,我们需要安装相应版本的Selenium和ChromeDriver,在命令行中输入以下代码即可安装:

|---|-------------------------------------------|
| 1 | composer ``require facebook/webdriver |

然后将ChromeDriver二进制文件(根据自己的本地Chrome版本下载相应版本的ChromeDrive)置于系统Path变量环境中,代码如下:

|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 | $webdriver = FacebookWebDriverRemoteRemoteWebDriver::create( ``'http://localhost:9515'``, FacebookWebDriverChromeChromeOptions::``class ); |

二、构建Selenium和ChromeDriver的封装类

Selenium封装类主要用来维护Selenium和ChromeDriver,避免重复创建、销毁,代码如下:

|----------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class Selenium { ``private static $driver``; ``private static $selenium``; ``public static function getInstance() ``{ ``if (null === self::``$selenium``) { ``$options = ``new ChromeOptions(); ``$options``->addArguments([``'--no-sandbox'``,``'--disable-extensions'``,``'--headless'``,``'--disable-gpu'``]); ``self::``$driver = RemoteWebDriver::create( ``'http://localhost:9515'``, ``DesiredCapabilities::chrome()->setCapability( ``ChromeOptions::CAPABILITY, ``$options ``) ``); ``self::``$selenium = ``new self(); ``} ``return self::``$selenium``; ``} ``public function __destruct() ``{ ``self::``$driver``->quit(); ``self::``$selenium = null; ``} ``public function getDriver() ``{ ``return self::``$driver``; ``} } |

注意,参数中的ChromeOptions主要是为了在无GUI(图形化界面)下仍能稳定运行,--no-sandbox参数是为了防止在linux系统下运行时报错。

三、创建网页源码解析类

爬虫系统的核心在于解析非静态页面,这里需要创建源码解析类,使用正则表达式或XPath表达式来定位和获取目标节点信息。

|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | class PageParser { ``private $pageSource``; ``public function __construct(string ``$pageSource``) ``{ ``$this``->pageSource = ``$pageSource``; ``} ``public function parse(string ``$expression``, ``$list = false) ``{ ``if (``$list``) { ``return $this``->parseList(``$expression``); ``} ``return $this``->parseSingle(``$expression``); ``} ``private function parseList(string ``$expression``) ``{ ``$domXpath = ``new DOMXPath(@DOMDocument::loadHTML(``$this``->pageSource)); ``$items = ``$domXpath``->query(``$expression``); ``$result = []; ``foreach (``$items as $item``) { ``array_push``(``$result``,trim(``$item``->nodeValue)); ``} ``return $result``; ``} ``private function parseSingle(string ``$expression``) ``{ ``$domXpath = ``new DOMXPath(@DOMDocument::loadHTML(``$this``->pageSource)); ``$item = ``$domXpath``->query(``$expression``)->item(0); ``if (``$item``) { ``return trim(``$item``->nodeValue); ``} ``return ''``; ``} } |

这里主要用到了DOMXPath类和DOMDocument类来解析页面中的HTML节点,分别通过parseList和parseSingle方法来定位和获取多个和一个目标节点的内容。

四、创建爬虫类

最后,我们需要构建一个专门爬取页面内容的爬虫类,代码如下:

|----------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Spider { ``private $selenium``; ``private $url``; ``public function __construct(``$url``) ``{ ``$this``->selenium = Selenium::getInstance(); ``$this``->url = ``$url``; ``$this``->selenium->getDriver()->get(``$url``); ``sleep(1); ``} ``public function __destruct() ``{ ``$this``->selenium->getDriver()->close(); ``$this``->selenium = null; ``} ``public function getContent(``$expression``, ``$list = false) ``{ ``$pageSource = ``$this``->selenium->getDriver()->getPageSource(); ``$parser = ``new PageParser(``$pageSource``); ``return $parser``->parse(``$expression``, ``$list``); ``} } |

该类的getContent方法接收两个参数,一个是目标节点的XPath表达式,另一个是是否获取多个内容。 getModelContent函数请求URL并解析节点来获取所需内容,该函数获取结束后关闭浏览器进程。

五、使用示例

最后,我们使用实际例子来说明如何使用这个爬虫类。假设我们需要从一个拥有多个a标签的网页上,爬取a标签中的href属性和文本信息。我们可以通过以下代码来实现:

|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 | $spider = ``new Spider(``'https://www.example.com'``); $aTags = ``$spider``->getContent(``'//a'``, true); foreach (``$aTags as $a``) { ``$href = ``$a``->getAttribute(``'href'``); ``$text = ``$a``->nodeValue; ``echo "``$href -> ``$text "; } |

在以上代码中,首先使用Spider类获取页面源码,然后通过XPath表达式获取多个a标签的节点信息,最后通过getAttribute和nodeValue方法获取每个a标签的href属性和文本。

六、总结

综上所述,本文通过介绍如何使用PHP和Selenium构建网页爬虫系统,并通过实际示例说明如何获取页面中的节点信息,该爬虫具有稳定性高、数据采集全面等优点,具有一定的应用价值。但同时需要注意的是,爬取数据时需要注意合法性和道德性,并遵守相关法律法规。

相关推荐
JaguarJack2 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo2 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack3 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo3 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack4 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay5 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954485 天前
CTF 伪协议
php
BingoGo7 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack7 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo8 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php