说明

  • QueryList是一套用于内容采集的PHP工具,它使用更加现代化的开发思想,语法简洁、优雅,可扩展性强。相比传统的使用晦涩的正则表达式来做采集,QueryList使用了更加强大而优雅的CSS选择器来做采集,大大降低了PHP做采集的门槛,同时也让采集代码易读易维护。

  • QueryList是直接获取的页面上的元素内容,而不是直接获取api中的内容。

  • 使用文档

安装

  1. 网址:https://querylist.cc/,新版环境要求php>=7.1

  2. composer安装命令:

  3. composer require jaeger/querylis

    执行composer命令后顺利安装的截图

  4. 如果上面的composer命令太慢,请使用国内镜像:

  5. composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

使用

说明:当时使用时是在tp5中测试使用的,所以下面的内容都是基于tp5进行举例的。

设置采集地址

$ql=QueryList::get($src);

获取单个数据

$data=$ql->find('div')->attr("id");//获取页面上一个div的id值

QueryList有个find()方法,用于采集单个元素,它通过jQuery选择器选择DOM元素,用法同jQuery的find()方法。

获取属性值

$ql=QueryList::get('https://www.iqshw.com/');
//获取第一张图片的链接地址,下面四种方法完全等价
$data[]=$ql->find('div')->attr('src');
$data[]=$ql->find('div')->src;
$data[]=$ql->find('div:eq(0)')->src;//等推获取第n张:img:eq(n-1)
$data[]=$ql->find('div')->eq(0)->src;//等推获取第n张:eq(n-1)
//获取其他属性值
$data[]=$ql->find('div')->alt;
//获取其它自定义属性值,只能获取一种
//获取所有属性值
$data[]=$ql->find('div')->attr("*");
//获取元素下的HTML内容
$data[]=$ql->find('#id')->html();
$data[]=$ql->find('#id .class')->html();
//获取其它自定义属性值,只能获取一种
//获取元素下的纯文本内容
$data[]=$ql->find('.class')->text();

获取多条数据

获取多个元素的单个属性值(QueryList中凡是涉及到集合的地方返回的都是Collection集合对象,这个对象有个all()方法,用于把当前对象转成数组,所以你会发现下面很多写法都是$data->all() )

$ql=QueryList::get('https://www.iqshw.com/');
//获取所有图片的src属性值
$data[]=$ql->find('img')->map(function ($item){
    return $item->src;
})->all();
//等价与下面这句话
$data[]=$ql->find('img')->attrs('src')->all();
//获取元素中所有的html内容和text内容
$data[]=$ql->find('#id')->htmls()->all();
$data[]=$ql->find('.class')->texts()->all();

列表采集

列表采集才是QueryList的核心功能,这里主要涉及到两个函数的用法:rules()和range()

$rules = [
    '规则名1' => ['选择器1','元素属性'],
    '规则名2' => ['选择器2','元素属性'],
    // ...
];
//代码示例:
$ql=QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules=[
    //采集标题
    'title'=>['.postTitle2','text'],
    //采集内容
    'text'=>['.c_b_p_desc','text'],
    //采集时间
    'time'=>['.dayTitle','text']
];
$data=$ql->rules($rules)->query()->getData()->all();
//等同于上面
$data=$ql->rules($rules)->queryData();

用range()函数来配合rules()进行循环采集列表内容,range()函数的作用是选择一个元素作为多个数据之间的“切片”。

$ql=QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules=[
    //采集标题
    'title'=>['.postTitle2','text'],
    //采集内容
    'text'=>['.c_b_p_desc','text'],
    //采集时间
    'time'=>['.dayTitle','text']
];
$range='.day';//切片选择器
$data=$ql->rules($rules)->range($range)->query()->getData()->all();

内容过滤

利用remove()来过滤不需要的内容:

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//移除选中html中的a标签
$data = $ql->find('.c_b_p_desc:eq(0)')->remove('a')->html();
//只保留a标签中的html内容
$data = $ql->find('.day:eq(0)')->find('a')->remove()->html();

列表采集时过滤不需要的元素,使用规则:

$rules = [
    '规则名1' => ['选择器1','元素属性','内容过滤选择器'],
    '规则名2' => ['选择器2','元素属性','内容过滤选择器'],
    // ...
];

内容过滤选择器参数不光可以定义要移除的内容还可以定义要保留的内容,多个值之间用空格隔开, 有如下2条规则:

  1. 内容移除规则:选择器名前面添加减号(-),表示移除该标签以及标签内容。

  2. 内容保留规则:选择器名前面没有减号(-)(此时选择器只能为HTML标签名,不支持其他选择器), 当要采集的[元素属性] 值为text时表示需要保留的HTML标签以及内容,为html时表示要过滤掉的 HTML标签但保留内容。

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
    //采集内容
    'text' => ['.c_b_p_desc', 'html','-a'],
    //采集时间
    'time' => ['.dayTitle', 'text']
];
$range = '.day';//切片选择器
$data = $ql->rules($rules)->range($range)->query()->getData()->all();

数据处理

获取到数据后进行二次处理:

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
    //采集内容
    'text' => ['.c_b_p_desc', 'html'],
    //采集时间
    'time' => ['.dayTitle', 'text']
];
$range = '.day';//切片选择器
$data = $ql->rules($rules)->range($range)->query()->getData(function($item){
    $qls = QueryList::html($item['text']);
    $qls->find('a')->remove();
    $item['content'] = $qls->find('')->html();
    return $item;
})->all();

乱码处理

$ql = QueryList::get('https://www.iqshw.com/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['a', 'text'],
];
$range = 'li';//切片选择器
//乱码处理,设置输出编码
$data = $ql->rules($rules)->range($range)
    ->encoding('UTF-8','GB2312')
    ->query()->getData()->all();
//如果设置输出参数无法解决乱码,那就使用removeHead()方法移除html头部
$data = $ql->rules($rules)->range($range)
    ->removeHead()->query()->getData()->all();
//或者
$data = $ql->rules($rules)->range($range)
    ->encoding('UTF-8','GB2312')
    ->removeHead()->query()->getData()->all();
//手动转码
$html=$text=iconv("GB2312","UTF-8",file_get_contents('https://www.iqshw.com/'));
$data = QueryList::html($html)->rules([
    'title' => ['.news-comm-wrap a ', 'text'],
])->range($range)->query()->getData()->all();

简化数据

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
];
$range = '.day';//切片选择器
//使用flatten()方法将多维集合转为一维的
$data = $ql->rules($rules)->range($range)->query()->getData()->flatten()->all();

截取数据

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
];
$range = '.day';//切片选择器
//take()方法返回给定数量项目的新集合,对最初的采集结果data进行处理:
$data = $ql->rules($rules)->range($range)->query()->getData()->take(2)->all();

反转数据顺序

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
];
$range = '.day';//切片选择器
//使用reverse()来倒转集合中的项目
$data = $ql->rules($rules)->range($range)->query()->getData()->reverse()->all();

过滤数据

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
];
$range = '.day';//切片选择器
//filter()方法用于按条件过滤数据,只保留满足条件的数据。
//只能过滤,不能修改添加原数据,如果需要修改添加则用getData
$data = $ql->rules($rules)->range($range)->query()->getData()
    ->filter(function ($item){
    return $item['title']!='PHP使用引用实现无限极分类';
})->all();

遍历数据

$ql = QueryList::get('https://www.cnblogs.com/yulongcode/');
//定义采集规则
$rules = [
    //采集标题
    'title' => ['.postTitle2', 'text'],
];
$range = '.day';//切片选择器
//map() 方法遍历集合并将每一个值传入给定的回调。
//该回调可以任意修改项目并返回,从而形成新的被修改过项目的集合。
$data = $ql->rules($rules)->range($range)->query()->getData()
    ->map(function ($item){
        $item['time']=time();
        return $item;
    })->all();

其他操作

  • attr()方法除了获取DOM元素的值外,还有第二个参数,用于设置元素属性值

  • text()方法是获取元素的纯文本内容,加参数表示设置元素内容

  • html()方法是获取元素的HTML内容,加参数表示设置元素HTML内容

    以上三个用法基本和jQuery相同,添加完后再获取,才会出现在获取的数据中。

  • append()追加元素

  • replaceWith()替换元素

  • removeAttr()移除元素属性

  • parent()用户获取当前元素的父级元素

  • next()和prev()用于获取当前元素临近的下一个元素和上一个元素

    更多使用说明请查看使用文档。