DOM解析单元素
学习DOM解析单个网页元素的属性值或内容。
QueryList有个find()
方法,用于DOM解析单个元素,它通过jQuery选择器选择DOM元素,用法同jQuery的find()
方法。
获取单个元素的单个属性
如果你有使用过jQuery的经验,就会发现下面的写法与jQuery的写法是一致的。
设置待DOM解析的HTML片段
php
use QL\QueryList;
$html = <<<STR
<div id="one">
<div class="two">
<a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片" abc="这是一个自定义属性">
<img class="second_pic" src="http://querylist.com/2.jpg" alt="这是图片2">
<a href="http://doc.querylist.cc">QueryList文档</a>
</div>
<span>其它的<b>一些</b>文本</span>
</div>
STR;
$ql = QueryList::html($html);
use QL\QueryList;
$html = <<<STR
<div id="one">
<div class="two">
<a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片" abc="这是一个自定义属性">
<img class="second_pic" src="http://querylist.com/2.jpg" alt="这是图片2">
<a href="http://doc.querylist.cc">QueryList文档</a>
</div>
<span>其它的<b>一些</b>文本</span>
</div>
STR;
$ql = QueryList::html($html);
获取第一张图片的属性
php
$rt = [];
//获取第一张图片的链接地址
//下面四种写法完全等价
$rt[] = $ql->find('img')->attr('src');
$rt[] = $ql->find('img')->src;
$rt[] = $ql->find('img:eq(0)')->src;
$rt[] = $ql->find('img')->eq(0)->src;
//获取第一张图片的alt属性
$rt[] = $ql->find('img')->alt;
//获取第一张图片的abc属性,注意这里获取定义属性的写法与普通属性的写法是一样的
$rt[] = $ql->find('img')->abc;
print_r($rt);
$rt = [];
//获取第一张图片的链接地址
//下面四种写法完全等价
$rt[] = $ql->find('img')->attr('src');
$rt[] = $ql->find('img')->src;
$rt[] = $ql->find('img:eq(0)')->src;
$rt[] = $ql->find('img')->eq(0)->src;
//获取第一张图片的alt属性
$rt[] = $ql->find('img')->alt;
//获取第一张图片的abc属性,注意这里获取定义属性的写法与普通属性的写法是一样的
$rt[] = $ql->find('img')->abc;
print_r($rt);
php
Array
(
[0] => http://querylist.com/1.jpg
[1] => http://querylist.com/1.jpg
[2] => http://querylist.com/1.jpg
[3] => http://querylist.com/1.jpg
[4] => 这是图片
[5] => 这是一个自定义属性
)
Array
(
[0] => http://querylist.com/1.jpg
[1] => http://querylist.com/1.jpg
[2] => http://querylist.com/1.jpg
[3] => http://querylist.com/1.jpg
[4] => 这是图片
[5] => 这是一个自定义属性
)
获取第二张图片的属性
php
$rt = [];
//获取第二张图片的alt属性
$rt[] = $ql->find('img')->eq(1)->alt;
//等价下面这句话
$rt[] = $ql->find('img:eq(1)')->alt;
//也等价下面这句话,通过class选择图片
$rt[] = $ql->find('.second_pic')->alt;
print_r($rt);
$rt = [];
//获取第二张图片的alt属性
$rt[] = $ql->find('img')->eq(1)->alt;
//等价下面这句话
$rt[] = $ql->find('img:eq(1)')->alt;
//也等价下面这句话,通过class选择图片
$rt[] = $ql->find('.second_pic')->alt;
print_r($rt);
php
Array
(
[0] => 这是图片2
[1] => 这是图片2
[2] => 这是图片2
)
Array
(
[0] => 这是图片2
[1] => 这是图片2
[2] => 这是图片2
)
获取元素的所有属性
属性匹配支持通配符*
,表示匹配当前元素的所有属性。
php
$rt = [];
$rt[] = $ql->find('img:eq(0)')->attr('*');
$rt[] = $ql->find('a:eq(1)')->attr('*');
print_r($rt);
$rt = [];
$rt[] = $ql->find('img:eq(0)')->attr('*');
$rt[] = $ql->find('a:eq(1)')->attr('*');
print_r($rt);
php
Array
(
[0] => Array
(
[src] => http://querylist.com/1.jpg
[alt] => 这是图片
[abc] => 这是一个自定义属性
)
[1] => Array
(
[href] => http://doc.querylist.cc
)
)
Array
(
[0] => Array
(
[src] => http://querylist.com/1.jpg
[alt] => 这是图片
[abc] => 这是一个自定义属性
)
[1] => Array
(
[href] => http://doc.querylist.cc
)
)
获取元素内的html内容或text内容
text内容与html内容的区别是,text内容中去掉了所有html标签,只剩下纯文本。
php
$rt = [];
// 获取元素下的HTML内容
$rt[] = $ql->find('#one>.two')->html();
// 获取元素下的text内容
$rt[] = $ql->find('.two')->text();
print_r($rt);
$rt = [];
// 获取元素下的HTML内容
$rt[] = $ql->find('#one>.two')->html();
// 获取元素下的text内容
$rt[] = $ql->find('.two')->text();
print_r($rt);
php
Array
(
[0] => <a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片" abc="这是一个自定义属性">
<img src="http://querylist.com/2.jpg" alt="这是图片2">
<a href="http://doc.querylist.cc">QueryList文档</a>
[1] => QueryList官网
QueryList文档
)
Array
(
[0] => <a href="http://querylist.cc">QueryList官网</a>
<img src="http://querylist.com/1.jpg" alt="这是图片" abc="这是一个自定义属性">
<img src="http://querylist.com/2.jpg" alt="这是图片2">
<a href="http://doc.querylist.cc">QueryList文档</a>
[1] => QueryList官网
QueryList文档
)
获取多个元素的单个属性
map()
方法用于遍历多个元素的集合,find()
方法返回的其实是多个元素的集合,这一点与jQuery也是一致的。
{info} QueryList中凡是涉及到集合的地方返回的都是
Collection
集合对象,这个对象有个all()
方法,用于把当前对象转成数组,所以你会发现下面很多写法都是$data->all() 。
获取class为two的元素下的所有图片的alt属性
php
$data1 = $ql->find('.two img')->map(function($item){
return $item->alt;
});
// 等价下面这句话
$data2 = $ql->find('.two img')->attrs('alt');
print_r($data1->all());
print_r($data2->all());
$data1 = $ql->find('.two img')->map(function($item){
return $item->alt;
});
// 等价下面这句话
$data2 = $ql->find('.two img')->attrs('alt');
print_r($data1->all());
print_r($data2->all());
php
Array
(
[0] => 这是图片
[1] => 这是图片2
)
Array
(
[0] => 这是图片
[1] => 这是图片2
)
Array
(
[0] => 这是图片
[1] => 这是图片2
)
Array
(
[0] => 这是图片
[1] => 这是图片2
)
获取选中元素的所有html内容和text内容
php
$texts = $ql->find('.two>a')->texts();
$htmls = $ql->find('#one span')->htmls();
print_r($texts->all());
print_r($htmls->all());
$texts = $ql->find('.two>a')->texts();
$htmls = $ql->find('#one span')->htmls();
print_r($texts->all());
print_r($htmls->all());
php
Array
(
[0] => QueryList官网
[1] => QueryList文档
)
Array
(
[0] => 其它的<b>一些</b>文本
)
Array
(
[0] => QueryList官网
[1] => QueryList文档
)
Array
(
[0] => 其它的<b>一些</b>文本
)
实战 - DOM解析IT之家文章页
如图DOM解析IT之家文章页的:文章标题、作者和正文内容。
php
use QL\QueryList;
$ql = QueryList::get('https://www.ithome.com/html/discovery/358585.htm');
$rt = [];
// DOM解析文章标题
$rt['title'] = $ql->find('h1')->text();
// DOM解析文章作者
$rt['author'] = $ql->find('#author_baidu>strong')->text();
// DOM解析文章内容
$rt['content'] = $ql->find('.post_content')->html();
print_r($rt);
use QL\QueryList;
$ql = QueryList::get('https://www.ithome.com/html/discovery/358585.htm');
$rt = [];
// DOM解析文章标题
$rt['title'] = $ql->find('h1')->text();
// DOM解析文章作者
$rt['author'] = $ql->find('#author_baidu>strong')->text();
// DOM解析文章内容
$rt['content'] = $ql->find('.post_content')->html();
print_r($rt);
php
Array
(
[title] => 巴基斯坦一城镇温度达50.2度:创下全球4月历史温度新高
[author] => 白猫
[content] => <p><a class="s_tag" href="https://www.ithome.com/" target="_blank">IT之家</a>5月6日消息 4月份就遇到超过50度的极端天气显然是不可想象的,不过这的的确确发生在我们的周围,目前在巴基斯坦的一个城镇,有气象观测站显示该地的温度最高达到50.2度,打破了全球有记录以来的四月最高温。</p>
<p><img src="//img.ithome.com/images/v2/t.png" w="600" h="400" class="lazy" title="巴基斯坦一城镇温度达50.2度:创下全球4月历史温度新高" data-original="https://img.ithome.com/newsuploadfiles/2018/3/20180323_103720_572.png" width="600" height="400"></p>
<p>根据天空新闻的报道,在位于巴基斯坦南部的纳瓦布沙在周一(4月30日)的时候出现了高达50.2度的气温,气象学家表示这或许是人类有史以来遇到的四月份最高的温度。</p>
<p>法国气象局的气象学家卡比奇安在推特上表示,巴基斯坦的这个小城镇不但是有史以来亚洲遇到的最高的四月气温,更有可能是全球四月的最高温,而也有网友表示由于过于炎热的天气,当地已经有不少人因为中暑而丧命。</p>
<p>全球极端天气专家克里斯托弗伯特也表示,四月份就达到50摄氏度极其罕见,纳瓦布沙的温度或将是人类有史以来遇到的温度最高的四月。农业学家表示巴基斯坦过高的温度会严重影响未来粮食的收割。</p>
)
Array
(
[title] => 巴基斯坦一城镇温度达50.2度:创下全球4月历史温度新高
[author] => 白猫
[content] => <p><a class="s_tag" href="https://www.ithome.com/" target="_blank">IT之家</a>5月6日消息 4月份就遇到超过50度的极端天气显然是不可想象的,不过这的的确确发生在我们的周围,目前在巴基斯坦的一个城镇,有气象观测站显示该地的温度最高达到50.2度,打破了全球有记录以来的四月最高温。</p>
<p><img src="//img.ithome.com/images/v2/t.png" w="600" h="400" class="lazy" title="巴基斯坦一城镇温度达50.2度:创下全球4月历史温度新高" data-original="https://img.ithome.com/newsuploadfiles/2018/3/20180323_103720_572.png" width="600" height="400"></p>
<p>根据天空新闻的报道,在位于巴基斯坦南部的纳瓦布沙在周一(4月30日)的时候出现了高达50.2度的气温,气象学家表示这或许是人类有史以来遇到的四月份最高的温度。</p>
<p>法国气象局的气象学家卡比奇安在推特上表示,巴基斯坦的这个小城镇不但是有史以来亚洲遇到的最高的四月气温,更有可能是全球四月的最高温,而也有网友表示由于过于炎热的天气,当地已经有不少人因为中暑而丧命。</p>
<p>全球极端天气专家克里斯托弗伯特也表示,四月份就达到50摄氏度极其罕见,纳瓦布沙的温度或将是人类有史以来遇到的温度最高的四月。农业学家表示巴基斯坦过高的温度会严重影响未来粮食的收割。</p>
)