程序员Laravel开发实践Laravel

简单的php爬网页

2018-11-10  本文已影响79人  3275508ab630

笔者用了两个第三方包

  1. https://github.com/kitetail/zttp 用来请求网页
  2. https://github.com/symfony/dom-crawler 获取网页指定内容

1. 安装第三方包

composer require kitetail/zttp
composer require symfony/dom-crawler

2. 访问网页

假设我们要抓取 http://www.w3school.com.cn/xpath/index.asp 这个网页的左侧栏目录。

左侧栏目录.png
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 的节点,点击 CopyCopy XPath

控制台.png
我们就拿到了路径
//*[@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 和最后两个 lixpath有两个谓语可以帮助我们 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等等,大家自行深入去学习。

上一篇 下一篇

猜你喜欢

热点阅读