采集列表

优采云 发布时间: 2020-08-10 15:46

  采集列表

  学习怎么批量采集数据。

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

  用法

  上一章节的实战部份有讲解到采集IT之家的文章页,代码如下:

  use QL\QueryList;

$ql = QueryList::get('https://www.ithome.com/html/discovery/358585.htm');

$rt = [];

// 采集文章标题

$rt['title'] = $ql->find('h1')->text();

// 采集文章作者

$rt['author'] = $ql->find('#author_baidu>strong')->text();

// 采集文章内容

$rt['content'] = $ql->find('.post_content')->html();

print_r($rt);

  通过这段采集代码相信你早已感受到了QueryList的简约与高贵,然而里面代码还可以变的更简练,下面我们来用rules()函数进一步简化代码:

  采集代码:

  use QL\QueryList;

$url = 'https://www.ithome.com/html/discovery/358585.htm';

// 定义采集规则

$rules = [

// 采集文章标题

'title' => ['h1','text'],

// 采集文章作者

'author' => ['#author_baidu>strong','text'],

// 采集文章内容

'content' => ['.post_content','html']

];

$rt = QueryList::get($url)->rules($rules)->query()->getData();

print_r($rt->all());

  采集结果:

  Array

(

[title] => 巴基斯坦一城镇温度达50.2度:创下全球4月历史温度新高

[author] => 白猫

[content] => <p>IT之家5月6日消息 4月份就遇到超过50度的极端天气显然是不可想象的,镇,有气象观测站显示该地的温度最高达到50.2度,打破了全球有记录以来的四月最高温。

  //img.ithome.com/images/v2/t.png

  根据天空新闻的报道,在位于巴基斯坦南部的纳瓦布沙在周一(4月30日)的时候出现了高达50.2度的气温,气象学家表示这或许是人类有史以来遇到的四月份最高的温度。

  法国气象局的气象学家卡比奇安在推特上表示,巴基斯坦的这个小城镇不但是有史以来亚洲遇到的最高的四月气温,更有可能是全球四月的最高温,而也有网友表示由于过于炎热的天气,当地已经有不少人因为中暑而丧命。

  全球极端天气专家克里斯托弗伯特也表示,四月份就达到50摄氏度极其罕见,纳瓦布沙的温度或将是人类有史以来遇到的温度最高的四月。农业学家表示巴基斯坦过高的温度会严重影响未来粮食的收割。

)

</p>

  $rules规则解释如下:

  $rules = [

'规则名1' => ['选择器1','元素属性'],

'规则名2' => ['选择器2','元素属性'],

// ...

];

  采集结果与上面的代码完全相同,注意这儿的采集结果是一个二维数组。

  queryData() 语法糖

  可能你会觉的列表采集的句型有一点点繁杂,如:

  $rt = QueryList::get($url)->rules($rules)->query()->getData();

print_r($rt->all());

  QueryList V4.0.4版本新增了一个queryData()语法糖来简化这些操作:

  $rt = QueryList::get($url)->rules($rules)->queryData();

print_r($rt);

  queryData()方法等同于query()-&gt;getData()-&gt;all() 。

  {primary} QueryList之所以这样设计,是为了便捷在各个环节挂载插件,如:query()-&gt;downloadImage()-&gt;getData(),获取数据之前 ,先用保存图片的插件把图片下载到本地并替换图片路径为本地路径。

  列表采集

  前面只说到采集文章页内容,通常情况下我们会先采集列表页,然后再循环采集列表中的整篇文章,采集列表须要用到range()函数来配合rules()函数。

  

  如图我们要采集IT之家的文章列表,我标记了不同的颜色来分解页面元素:

  首先要剖析出白色区域的选择器,我们称之为切块选择器或范围选择器,也就是range 。

  

  如图,利用浏览器的开发者工具可以很容易剖析出切块选择器为:.ulcl&gt;li,然后我们须要在这每位切块区域中去采集文章的标题、文章链接、简介以及缩略图,利用同样的方法剖析出每位元素的选择器,这里不再赘言,最终列表采集代码为:

  采集代码:

  use QL\QueryList;

$url = 'https://it.ithome.com/ityejie/';

// 元数据采集规则

$rules = [

​ // 采集文章标题

​ 'title' => ['h2>a','text'],

​ // 采集链接

​ 'link' => ['h2>a','href'],

​ // 采集缩略图

​ 'img' => ['.list_thumbnail>img','src'],

​ // 采集文档简介

​ 'desc' => ['.memo','text']

];

// 切片选择器

$range = '.content li';

$rt = QueryList::get($url)->rules($rules)

​ ->range($range)->query()->getData();

print_r($rt->all());

  采集结果:

  Array

(

​ [0] => Array

​ (

​ [title] =>

​ [link] =>

​ =>

​ [desc] =>

​ )

[1] => Array

(

[title] => 快讯:iOS版QQ大面积闪退(网友反映已恢复)

[link] => https://www.ithome.com/html/it/358734.htm

[img] => //img.ithome.com/images/v2/grey.gif

[desc] => iOS版QQ大面积闪退,原因未知。目前根据IT之家的网友反映,目前iOS版本的QQ已经恢复,但是近期的消息记录已经消失

)

[2] => Array

(

[title] => 阿里影业公布截至近15个月业绩:营收33亿元,增幅130%

[link] => https://www.ithome.com/html/it/358728.htm

[img] => //img.ithome.com/images/v2/grey.gif

[desc] => 阿里影业集团公布截至2018年3月31日的十五个月财务业绩:报告期内公司营业收入达到33.03亿元,较上一年同期十五个月的14.32亿元,增长幅度超130%

)

// ....

  数据是采集回来了,但我们发觉有一点瑕疵,结果上面有一条结果是空的,且文章缩略图链接不正确。

  [img]https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LAmB2ogFw3OY-4SNqia%2F-LBvFoEfWyQfvNZGC5jN%2F-LBvGtAAgikOPK3_2yPg%2FWX20180507-234518.png?alt=media&token=5975c46b-93dc-4b75-81f4-f623a8852929

  如图我们再度剖析页面可以获知,第一条切块区域是广告,所以采集的第一条结果为空;而文章列表的缩略图使用了懒加载,所以图片的真正链接在img的data-original属性上,修正后的代码如下:

  采集代码:

   use QL\QueryList;

$url = 'https://it.ithome.com/ityejie/';

// 元数据采集规则

$rules = [

​ // 采集文章标题

​ 'title' => ['h2>a','text'],

​ // 采集链接

​ 'link' => ['h2>a','href'],

​ // 采集缩略图,真正的图片链接在data-original属性上

​ 'img' => ['.list_thumbnail>img','data-original'],

​ // 采集文档简介

​ 'desc' => ['.memo','text']

];

// 切片选择器,跳过第一条广告

$range = '.content li:gt(0)';

$rt = QueryList::get($url)->rules($rules)

​ ->range($range)->query()->getData();

print_r($rt->all());

  采集结果:

  Array

(

[0] => Array

(

[title] => 快讯:iOS版QQ大面积闪退(网友反映已恢复)

[link] => https://www.ithome.com/html/it/358734.htm

[img] => //img.ithome.com/newsuploadfiles/thumbnail/2018/5/358734_240.jpg

[desc] => iOS版QQ大面积闪退,原因未知。目前根据IT之家的网友反映,目前iOS版本的QQ已经恢复,但是近期的消息记录已经消失

)

[1] => Array

(

[title] => 阿里影业公布截至近15个月业绩:营收33亿元,增幅130%

[link] => https://www.ithome.com/html/it/358728.htm

[img] => //img.ithome.com/newsuploadfiles/thumbnail/2018/5/358728_240.jpg

[desc] => 阿里影业集团公布截至2018年3月31日的十五个月财务业绩:报告期内公司营业收入达到33.03亿元,较上一年同期十五个月的14.32亿元,增长幅度超130%

)

// ....

)

  就这样我们借助QueryList太轻松就采集到了IT之家的文章列表以及文章内容。

  关于技巧的调用次序

  get()、rules()和range() 这几个方式都属于QueryList属性设置方式,所以调用次序可以随便,所以下边这几种写法都是等价的:

   QueryList::get($url)->rules($rules)->range($range)->query()->getData();

QueryList::rules($rules)->get($url)->range($range)->query()->getData();

QueryList::range($range)->rules($rules)->get($url)->query()->getData();

  根据此特点,这里有些使用的小技巧:

  // 待采集的同一个网站的网页集合

$urls = [

'http://xxx.com/1.html',

'http://xxx.com/2.html',

'http://xxx.com/3.html',

// ...

];

// 由于采集的都是同一个网站的网页,所以采集规则是可以复用的

$ql = QueryList::rules([...])->range('...');

foreach ($urls as $url) {

$data = $ql->get($url)->query()->getData();

// ...

}

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线