如何使用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构建网页爬虫系统,并通过实际示例说明如何获取页面中的节点信息,该爬虫具有稳定性高、数据采集全面等优点,具有一定的应用价值。但同时需要注意的是,爬取数据时需要注意合法性和道德性,并遵守相关法律法规。

相关推荐
两个人的幸福17 小时前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo3 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack3 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户3074596982074 天前
PHP 扩展——从入门到理解
php
太岁又沐风4 天前
复现并修掉ART hook框架 Pine 调用原方法时的偶发 SIGSEGV
爬虫
鹏仔先生4 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下5 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
隔窗听雨眠5 天前
大模型加爬虫上篇:技术融合与架构革新
爬虫·架构
xingpanvip5 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
程序员小远5 天前
自动化测试基础知识总结
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例