笔者用了两个第三方包
1. 安装第三方包
composer require kitetail/zttp
composer require symfony/dom-crawler
2. 访问网页
假设我们要抓取 http://www.w3school.com.cn/xpath/index.asp 这个网页的左侧栏目录。
用
Zttp
请求这个地址
$response = Zttp::get('http://www.w3school.com.cn/xpath/index.asp');
$body = $response->body();
这个 $body
就是网页源码字符串了,但是打印它出现的中文字是乱码。我们看到网页源代码其中16行
<meta charset="gbk" />
把 gbk
转成 utf-8
$body = iconv('GBK', 'UTF-8', $body);
3. 获取指定内容
拿到指定内容有很多种方式,比如正则,JQuery
选择器,css
选择器。笔者下面用 xpath
来选取内容。
在 chrome
右键定位内容选择检查,右键控制台中 html
的节点,点击 Copy
,Copy XPath
我们就拿到了路径
//*[@id="course"]/ul[1]/li[1]/a
把上面的 $body
放入 Crawler
类里进行操作,用上面的 xpath
路径就能拿到想要的内容
$crawler = new Crawler();
$crawler->addHtmlContent(trim($body));
$data1 = $crawler->filterXPath('//*[@id="course"]/ul[1]/li[1]/a');
$text1 = $data1->text();
$data2 = $crawler->filterXPath('//*[@id="course"]/ul[1]/li[2]/a');
$text2 = $data2->text();
...
上面的 li[1]
就和我们取数组中的值一样,不一样的是下标从 1
开始。li
有很多个,我们需要循环去取,修改一下上面的代码
$data = $crawler->filterXPath('//*[@id="course"]/ul[1]/li')->each(function (Crawler $node, $i) {
return $node->text();
}); //$data 是数组,是我们最终想要的值
data.png
注意
xpath
,下面的是取了所有的 li
,$node
就是一个个 li
。
4. 其他
假如我们要 去掉 前两个 li
和最后两个 li
。xpath
有两个谓语可以帮助我们 position()
和 last()
。
$data = $crawler->filterXPath('//*[@id="course"]/ul[1]/li[position()>2 and position()<last()-1]')->each(function (Crawler $node, $i) {
return $node->text();
});
在括号里设置条件就能取出我们想要的范围。当然 xpath
还有其他语法,可以去文档中学习,复杂的爬虫会涉及到账号登录,多线程,动态ip等等,大家自行深入去学习。
网友评论