PHP 爬虫利器 QueryList 入门与使用指南
之前开发小程序时,我用 Go 语言结合 goquery 写了个数据采集脚本。起初运行稳定,但随着抓取目标网站的频繁改版,采集规则需要不断调整。由于 Go 是静态编译语言,每次微调逻辑都要重新编译部署,显得过于繁琐。考虑到小程序后端本身就是 PHP 构建的,为了统一技术栈并降低维护成本,我转向了 PHP 的方案,并发现了 QueryList 这个工具。
### 什么是 QueryList
QueryList 是一款基于 phpQuery 构建的简洁、优雅且具备高扩展性的 PHP 网页数据采集框架。它的设计初衷是打造一个“优雅的渐进式 PHP DOM 解析框架”,旨在让 DOM 节点的解析过程变得自然且易于上手。不论是请求网页 HTML,还是从中精准提取结构化数据,QueryList 都能确保你的代码保持干净整洁。
### QueryList 的特性
它的功能覆盖面极广,基本能满足日常 PHP 爬虫开发的各种需求:
- 完美兼容 jQuery CSS3 DOM 选择器,几乎没有学习门槛;
- 提供与 jQuery 高度相似 DOM 操作 API,体验顺滑;
- 内置通用的列表抓取机制,处理列表页游刃有余;
- 拥有强大的 HTTP 请求组件,支持模拟登录、伪装浏览器标识、绑定 HTTP 代理等进阶操作;
- 自带乱码处理方案,彻底告别编码转换烦恼;
- 具备强大的内容过滤机制,可直接复用 jQuery 选择器进行过滤;
- 采用模块化架构,扩展性极强;
- API 设计直观且富有表现力;
- 提供高质量的文档,助力开发者快速入门;
- 拥有丰富的插件生态系统,可按需增强功能;
- 设有专业的问答社区及交流群,遇到技术难点能获得协助。
综合而言,QueryList 堪称 PHP 爬虫领域的“瑞士军刀”,既适用于轻量级的简单抓取,也能从容应对复杂场景。
### QueryList 安装
该工具的安装过程极其简便,只需通过 Composer 执行如下命令即可:
```composer require jaeger/querylist```
依赖安装完毕后,即可在业务代码中直接引入使用。
### QueryList 使用
它内置了数个核心方法,专门用于发起网络请求并处理页面数据:
- `QueryList::get($url)`:发起 GET 请求并获取目标网页内容;
- `QueryList::post($url, $data)`:发起 POST 请求并提交参数数据;
- `QueryList::getHtml($url)`:直接抓取页面的 HTML 源代码。
### 简单示例
```php
use QL\QueryList;
$images = QueryList::get('http://www.xxxxxx.com')->find('img')->attrs('src');
print_r($images->all());
```
### 搜索结果抓取示例
假设我们需要采集某度搜索结果页面中的标题及对应链接,可以这样编写代码:
```php
use QL\QueryList;
$data = QueryList::get('https://www.某度.com/s?wd=QueryList', null, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Accept-Encoding' => 'gzip, deflate, br',
]
])->rules([
'title' => ['h3', 'text'],
'link' => ['h3>a', 'href']
])
->range('.result')
->queryData();
print_r($data);
```
如果只需单独提取标题列表或链接列表,也可以拆分编写:
```php
$ql = QueryList::get('https://www.某度.com/s?wd=QueryList', null, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Accept-Encoding' => 'gzip, deflate, br',
]
]);
$titles = $ql->find('h3>a')->texts(); // 获取搜索结果标题列表
$links = $ql->find('h3>a')->attrs('href'); // 获取搜索结果链接列表
print_r($titles->all());
print_r($links->all());
```
### 多层嵌套循环示例
```php
$url = 'https://www.xxx.cn/xxxxx/xxxx.php';
$ql = QueryList::get($url);
$data = $ql->find('.class1')->map(function ($row) {
$type = $row->find('.class2')->html();
$list = $row->find('span')->map(function ($row1) {
$title = $row1->find('a')->html();
$url = $row1->find('a')->attr('href');
preg_match_all('/[((]([\x{4e00}-\x{9fa5}]{2,4})[))]/u', $row1->text(), $matches);
return [
'title' => $title,
'author' => $matches[1][0]??'',
'url' => sprintf("https://www.xxx.cn%s", $url)
];
})->all();
return [
'type' => $type,
'data' => $list
];
})->all();
```
借助上述 API 组合,仅用少量 PHP 代码就能搞定复杂的网页数据提取任务,而且后期的维护与逻辑修改也极为便捷。
### 与 goquery 相比
就语法体验而言,其实两者的差异并不悬殊,但 Go 语言在编写和调试时相对繁琐一些,代码示例如下:
```go
resp, err := http.Get("https://www.某度.com/xxxxxxx?tab=xxxxxxx")
if err != nil {
resultResp.Code = 1
resultResp.Err = "Failed to fetch data"
c.JSON(http.StatusOK, resultResp)
return
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
resultResp.Code = 1
resultResp.Err = "Failed to read response body"
c.JSON(http.StatusOK, resultResp)
}
doc.Find(".class1").Each(func(i int, s *goquery.Selection) {
text1 := s.Find(".class2").Text()
href1, _ := s.Find(".class3").Attr("href")
imgsrc1, _ := s.Find("a img").Attr("src")
})
```
### 写在最后
互联网上普遍推崇用 Python 编写爬虫,不可否认 Python 的第三方生态确实繁荣。但实际上,无论是 Go 还是 PHP,同样能出色完成爬虫任务。底层抓取原理大同小异,关键在于挑选最契合自身及团队技术背景的方案。尽量避免在单一项目中强行混搭多种语言,以免徒增运维与部署的复杂度。如果你的系统后端已全面采用 PHP,那么 QueryList 绝对能让你在处理网页采集时事半功倍。
### 什么是 QueryList
QueryList 是一款基于 phpQuery 构建的简洁、优雅且具备高扩展性的 PHP 网页数据采集框架。它的设计初衷是打造一个“优雅的渐进式 PHP DOM 解析框架”,旨在让 DOM 节点的解析过程变得自然且易于上手。不论是请求网页 HTML,还是从中精准提取结构化数据,QueryList 都能确保你的代码保持干净整洁。
### QueryList 的特性
它的功能覆盖面极广,基本能满足日常 PHP 爬虫开发的各种需求:
- 完美兼容 jQuery CSS3 DOM 选择器,几乎没有学习门槛;
- 提供与 jQuery 高度相似 DOM 操作 API,体验顺滑;
- 内置通用的列表抓取机制,处理列表页游刃有余;
- 拥有强大的 HTTP 请求组件,支持模拟登录、伪装浏览器标识、绑定 HTTP 代理等进阶操作;
- 自带乱码处理方案,彻底告别编码转换烦恼;
- 具备强大的内容过滤机制,可直接复用 jQuery 选择器进行过滤;
- 采用模块化架构,扩展性极强;
- API 设计直观且富有表现力;
- 提供高质量的文档,助力开发者快速入门;
- 拥有丰富的插件生态系统,可按需增强功能;
- 设有专业的问答社区及交流群,遇到技术难点能获得协助。
综合而言,QueryList 堪称 PHP 爬虫领域的“瑞士军刀”,既适用于轻量级的简单抓取,也能从容应对复杂场景。
### QueryList 安装
该工具的安装过程极其简便,只需通过 Composer 执行如下命令即可:
```composer require jaeger/querylist```
依赖安装完毕后,即可在业务代码中直接引入使用。
### QueryList 使用
它内置了数个核心方法,专门用于发起网络请求并处理页面数据:
- `QueryList::get($url)`:发起 GET 请求并获取目标网页内容;
- `QueryList::post($url, $data)`:发起 POST 请求并提交参数数据;
- `QueryList::getHtml($url)`:直接抓取页面的 HTML 源代码。
### 简单示例
```php
use QL\QueryList;
$images = QueryList::get('http://www.xxxxxx.com')->find('img')->attrs('src');
print_r($images->all());
```
### 搜索结果抓取示例
假设我们需要采集某度搜索结果页面中的标题及对应链接,可以这样编写代码:
```php
use QL\QueryList;
$data = QueryList::get('https://www.某度.com/s?wd=QueryList', null, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Accept-Encoding' => 'gzip, deflate, br',
]
])->rules([
'title' => ['h3', 'text'],
'link' => ['h3>a', 'href']
])
->range('.result')
->queryData();
print_r($data);
```
如果只需单独提取标题列表或链接列表,也可以拆分编写:
```php
$ql = QueryList::get('https://www.某度.com/s?wd=QueryList', null, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
'Accept-Encoding' => 'gzip, deflate, br',
]
]);
$titles = $ql->find('h3>a')->texts(); // 获取搜索结果标题列表
$links = $ql->find('h3>a')->attrs('href'); // 获取搜索结果链接列表
print_r($titles->all());
print_r($links->all());
```
### 多层嵌套循环示例
```php
$url = 'https://www.xxx.cn/xxxxx/xxxx.php';
$ql = QueryList::get($url);
$data = $ql->find('.class1')->map(function ($row) {
$type = $row->find('.class2')->html();
$list = $row->find('span')->map(function ($row1) {
$title = $row1->find('a')->html();
$url = $row1->find('a')->attr('href');
preg_match_all('/[((]([\x{4e00}-\x{9fa5}]{2,4})[))]/u', $row1->text(), $matches);
return [
'title' => $title,
'author' => $matches[1][0]??'',
'url' => sprintf("https://www.xxx.cn%s", $url)
];
})->all();
return [
'type' => $type,
'data' => $list
];
})->all();
```
借助上述 API 组合,仅用少量 PHP 代码就能搞定复杂的网页数据提取任务,而且后期的维护与逻辑修改也极为便捷。
### 与 goquery 相比
就语法体验而言,其实两者的差异并不悬殊,但 Go 语言在编写和调试时相对繁琐一些,代码示例如下:
```go
resp, err := http.Get("https://www.某度.com/xxxxxxx?tab=xxxxxxx")
if err != nil {
resultResp.Code = 1
resultResp.Err = "Failed to fetch data"
c.JSON(http.StatusOK, resultResp)
return
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
resultResp.Code = 1
resultResp.Err = "Failed to read response body"
c.JSON(http.StatusOK, resultResp)
}
doc.Find(".class1").Each(func(i int, s *goquery.Selection) {
text1 := s.Find(".class2").Text()
href1, _ := s.Find(".class3").Attr("href")
imgsrc1, _ := s.Find("a img").Attr("src")
})
```
### 写在最后
互联网上普遍推崇用 Python 编写爬虫,不可否认 Python 的第三方生态确实繁荣。但实际上,无论是 Go 还是 PHP,同样能出色完成爬虫任务。底层抓取原理大同小异,关键在于挑选最契合自身及团队技术背景的方案。尽量避免在单一项目中强行混搭多种语言,以免徒增运维与部署的复杂度。如果你的系统后端已全面采用 PHP,那么 QueryList 绝对能让你在处理网页采集时事半功倍。
· 0 个赞
· 0 个赞
· 0 个赞
· 0 个赞
· 0 个赞
· 0 个赞
· 0 个赞
· 0 个赞