处理采集结果

QueryList返回的集合数据均为Collection集合对象而非普通数组,目的就是为了方便处理采集结果数据。


QueryList引入了Laravel中Collection集合对象,它提供了一个更具可读性的、更便于处理数组数据的封装。下面通过几个例子来说明它的用法,更多用法可以去查看Laravel文档。

Collection文档:https://d.laravel-china.org/docs/5.4/collections

例子

采集所有图片链接,采集目标:

  1. $html =<<<STR
  2. <div class="xx">
  3. <img data-src="/path/to/1.jpg" alt="">
  4. </div>
  5. <div class="xx">
  6. <img data-src="/path/to/2.jpg" alt="">
  7. </div>
  8. <div class="xx">
  9. <img data-src="/path/to/3.jpg" alt="">
  10. </div>
  11. STR;

采集代码:

  1. $data = QueryList::html($html)->rules(array(
  2. 'image' => array('.xx>img','data-src')
  3. ))->query()->getData(function($item){
  4. return $item;
  5. });
  6. print_r($data->all());

采集结果:

  1. Array
  2. (
  3. [0] => Array
  4. (
  5. [image] => /path/to/1.jpg
  6. )
  7. [1] => Array
  8. (
  9. [image] => /path/to/2.jpg
  10. )
  11. [2] => Array
  12. (
  13. [image] => /path/to/3.jpg
  14. )
  15. )

简化数据

如果我们想要的结果是一位数组,而非二位数组,那该怎么做呢?

可以使用flatten()方法将多维集合转为一维的,对上面的采集结果data进行处理:

  1. $rt = $data->flatten()->all();
  2. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [0] => /path/to/1.jpg
  4. [1] => /path/to/2.jpg
  5. [2] => /path/to/3.jpg
  6. )

截取数据

如果我们只想要前2条数据,其它数据都是多余的,那该怎么做呢?

take() 方法返回给定数量项目的新集合,对最初的采集结果data进行处理:

  1. $rt = $data->take(2)->all();
  2. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [0] => Array
  4. (
  5. [image] => /path/to/1.jpg
  6. )
  7. [1] => Array
  8. (
  9. [image] => /path/to/2.jpg
  10. )
  11. )

你也可以传入负整数从集合末尾开始获取指定数量的项目,下面获取data数据中最后2条数据:

  1. $rt = $data->take(-2)->all();
  2. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [1] => Array
  4. (
  5. [image] => /path/to/2.jpg
  6. )
  7. [2] => Array
  8. (
  9. [image] => /path/to/3.jpg
  10. )
  11. )

翻转数据顺序

某些情况下我们需要翻转数据顺序,比如:采集论坛的帖子列表,帖子默认是按照发布日期由新到旧排序的,但我们把这些数据存入数据库的时候,想要按照发布日期由旧到新存入。

reverse() 方法用来倒转集合中项目的顺序:

  1. $rt = $data->reverse()->all();
  2. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [2] => Array
  4. (
  5. [image] => /path/to/3.jpg
  6. )
  7. [1] => Array
  8. (
  9. [image] => /path/to/2.jpg
  10. )
  11. [0] => Array
  12. (
  13. [image] => /path/to/1.jpg
  14. )
  15. )

过滤数据

filter()方法用于按条件过滤数据,只保留满足条件的数据。

下面例子过滤掉图片路径为/path/to/2.jpg的值。

采集代码:

  1. $rt = $data->filter(function($item){
  2. return $item['image'] != '/path/to/2.jpg';
  3. })->all();
  4. print_r($rt);

采集果:

  1. Array
  2. (
  3. [0] => Array
  4. (
  5. [image] => /path/to/1.jpg
  6. )
  7. [2] => Array
  8. (
  9. [image] => /path/to/3.jpg
  10. )
  11. )

遍历数据,依次处理每一项数据

map() 方法遍历集合并将每一个值传入给定的回调。该回调可以任意修改项目并返回,从而形成新的被修改过项目的集合。下面遍历data并补全图片链接地址:

  1. $rt = $data->map(function($item){
  2. $item['image'] = 'http://xxx.com'.$item['image'];
  3. return $item;
  4. })->all();
  5. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [0] => Array
  4. (
  5. [image] => http://xxx.com/path/to/1.jpg
  6. )
  7. [1] => Array
  8. (
  9. [image] => http://xxx.com/path/to/2.jpg
  10. )
  11. [2] => Array
  12. (
  13. [image] => http://xxx.com/path/to/3.jpg
  14. )
  15. )

连贯操作

Collection对象的所有方法都是可以连贯操作的,比如下面操作,先翻转数数据顺序,然后补全图片链接,最后截取前2条数据:

  1. $rt = $data->reverse()->map(function($item){
  2. $item['image'] = 'http://xxx.com'.$item['image'];
  3. return $item;
  4. })->take(2)->all();
  5. print_r($rt);

输出结果:

  1. Array
  2. (
  3. [2] => Array
  4. (
  5. [image] => http://xxx.com/path/to/3.jpg
  6. )
  7. [1] => Array
  8. (
  9. [image] => http://xxx.com/path/to/2.jpg
  10. )
  11. )
{primary} 大家可以举一反三,更多用法查看Collection文档。