PHP 爬虫体验(一) - 使用dom-crawler和guzzle实现基本的爬虫
网络爬虫在大数据时代可以非常高效地自动进行数据的收集处理,而传统爬虫最简单也是最基本的功能实现原理即是下载网页,然后通过抽取页面元素来达到收集信息的目的。
PHP作为一门灵活易用的脚本语言,实现这些功能自然是不在话下的。
这里实现爬虫基于两个组件:
guzzle:最好用的PHP HTTP客户端,用来进行爬取页面的请求,异步请求和并发请求功能可以用来实现一些后期的扩展功能。
dom-crawler:symphony的Dom分析组件,可以用来分析HTML页面Dom元素和XML文件,用来进行页面分析。
两个组件在项目中都可以很方便地使用composer进行安装,这里以博客园的文章为例,使用这两个组件实现最简单的页面抓取,抓取我个人博客园首页的文章摘要和链接。
代码如下:
1 require_once __DIR__ . '/vendor/autoload.php'; 2 3 use GuzzleHttp\Client; 4 use Symfony\Component\DomCrawler\Crawler; 5 6 run(); 7 function run() 8 { 9 //要爬取的页面地址为我的博客园主页 10 $url = "http://www.cnblogs.com/jackiebao/"; 11 //伪造浏览器UA 12 $headers = [ 13 'user-agent' => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', 14 ]; 15 $client = new Client([ 16 'timeout' => 20, 17 'headers' => $headers 18 ]); 19 //发送请求获取页面内容 20 $response = $client->request('GET', $url)->getBody()->getContents(); 21 22 $data = []; 23 $crawler = new Crawler(); 24 $crawler->addHtmlContent($response); 25 26 //使用crawler进行页面内容分析 27 try{ 28 //这里使用的是xpath语法,轮询forFlow子类day中的元素,既页面上每一篇文章的块状元素,并且进行内容获取 29 $crawler->filterXPath('//div[contains(@class, "forFlow")]/div[contains(@class, "day")]')->each(function(Crawler $node, $i) use (&$data){ 30 $item = [ 31 'date' => $node->filterXPath('//div[contains(@class, "dayTitle")]/a')->text(), 32 'title' => $node->filterXPath('//div[contains(@class, "postTitle")]/a')->text(), 33 'abstract' => $node->filterXPath('//div[contains(@class, "postCon")]/div')->text(), 34 'url' => $node->filterXPath('//div[contains(@class, "postCon")]/div/a')->attr('href'), 35 ]; 36 $data[] = $item; 37 }); 38 }catch (\Exception $e){ 39 echo $e->getMessage() . PHP_EOL; 40 } 41 //打印结果 42 print_r($data); 43 }
打印出来的结果为:
Array ( [0] => Array ( [date] => 2018年4月27日 [title] => windows环境下给PHP增加rdkafka扩展 [abstract] => 摘要: 因为工作需要kafka作为消息中间件,所以在本地开发环境进行测试的时候需要给PHP添加rdkafka扩展,使用PHP作为producer或者cosumer,在此纪录一下rdkafka的安装过程。 扩展下载地址:http://pecl.php.net/package/rdkafka 根据自身PHP版本阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/8962804.html ) [1] => Array ( [date] => 2018年2月24日 [title] => 在亚马逊aws服务器上添加Google BBR支持 [abstract] => 摘要: 参考文章: https://51.ruyo.net/2783.html http://blog.csdn.net/VgFengYe/article/details/78609040 官方 quick start文档:https://github.com/google/bbr/blob/master/阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/8466232.html ) [2] => Array ( [date] => 2018年2月22日 [title] => PHP static关键字和self关键字的区别 [abstract] => 摘要: 在PHP的一个类中,带有static关键字的方法和属性被称为静态方法和静态属性,这样的方法和属性可以通过类直接访问,而不需要通过类对应的实例来进行访问,在类中访问静态变量以及静态属性的时候,可以使用self关键字和static关键字,两种访问方式看起来似乎没有区别,但是实际上还是不一样的 运行之后的阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/8459899.html ) [3] => Array ( [date] => 2018年2月6日 [title] => linux系统mysql忘记密码处理 [abstract] => 摘要: 最近开始重新拾掇自己优惠时贪便宜买的一台京东云主机,然而早已经将当年集成环境一键安装时设置的mysql密码给忘了。 于是度娘了解决办法,大致分为以下步骤: 结果执行之后报这个错误 “Unknown column 'password' in 'field list'”。 后查询得知mysql在5.7版阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/8424672.html ) [4] => Array ( [date] => 2018年1月25日 [title] => PHP7 新增加的两种运算符 [abstract] => 摘要: 太空舱运算符: 空合并运算符:阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/8352383.html ) [5] => Array ( [date] => 2017年4月25日 [title] => PHP trait 特性 [abstract] => 摘要: trait是PHP自5.4版本之后加入的一种新的代码复用机制,是一种细粒度代码复用的方法。官方文档对于trait给出的解释是: 自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。 Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/6763388.html ) [6] => Array ( [date] => 2017年1月23日 [title] => PHP 字符串拆分函数 [abstract] => 摘要: function str_split_utf8($str) { $split = 1; $array = array(); for ($i = 0; $i 127) { if ($value >= 192 && $value = 224 && $value = 240 && $value <= 247) { ...阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/6344173.html ) [7] => Array ( [date] => 2016年10月25日 [title] => Windows 环境下php安装openssl证书 [abstract] => 摘要: 新的电脑安装了PHP、设置好环境变量之后安装了composer,想要通过composer安装Yii2,结果出现了如下报错: 检查发现php.ini里面的extension=php_openssl.dll已开启,如提示所说问题的原因是证书认证失败。 解决方法: http://curl.haxx.se/阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/5996770.html ) [8] => Array ( [date] => 2016年7月21日 [title] => PHP 按照多个键值给数组分组合并 [abstract] => 摘要: 简介: $array 为一堆数组,各数组键值为固定 $keys为分组依据,在$array中按照$keys所指定的键值将数组分组,并且将除$keys指定键值对应的值以外的值合并 输出:阅读全文 [url] => https://www.cnblogs.com/jackiebao/p/5691094.html ) )
得到这样格式化的数据就很方便进行进一步的处理了,而最基础的爬虫功能也就实现了,实际上是非常简单的。