基于curl数据采集之单页面并行采集函数get_htmls的使用


Posted in PHP onApril 28, 2013

用第一篇的get_html()实现简单的数据采集,由于是一个一个执行才采集数据的传输时间就会是所有页面下载的总时长,一个页面假设1秒,那么10个页面就是10秒了。所幸curl还提供了并行处理的功能。

要写一个并行采集的函数,先要了解要采集什么样的页面,对采集的页面用什么请求,才能写出一个相对常用的函数。

功能需求分析:

返回什么?

当然每一个页面的html集合成的数组

传递什么参数?

编写get_html()时,我们知道了可以用options数组来传递更多的curl参数,那么多页面同时采集函数的编写这种特性也得保留下来。

什么类型的参数?

无论是请求网页HTML,还是调用互联网api接口,get和post传递参数总是请求同一个页面或者接口,只是参数不同罢了。那么参数的类型是:

get_htmls($url,$options);

$url 是string

$options,是一个二维数组,每一个页面的参数为一个数组。

这样的话,貌似解决了问题。但是我找遍了curl的手册都没有看到get的参数传递在什么地方,所以只能$url 是数组的形式传递并且增加一个method参数

函数的原型就定下来了get_htmls($urls,$options = array, $method = ‘get');代码如下:

function get_htmls($urls, $options = array(), $method = 'get'){
     $mh = curl_multi_init();
     if($method == 'get'){//get方式传值 最常用
         foreach($urls as $key=>$url){
             $ch = curl_init($url);
             $options[CURLOPT_RETURNTRANSFER] = true;
             $options[CURLOPT_TIMEOUT] = 5;
             curl_setopt_array($ch,$options);
             $curls[$key] = $ch;
             curl_multi_add_handle($mh,$curls[$key]);
         }
     }elseif($method == 'post'){//post方式传值 
         foreach($options as $key=>$option){
             $ch = curl_init($urls);
             $option[CURLOPT_RETURNTRANSFER] = true;
             $option[CURLOPT_TIMEOUT] = 5;
             $option[CURLOPT_POST] = true;
             curl_setopt_array($ch,$option);
             $curls[$key] = $ch;
             curl_multi_add_handle($mh,$curls[$key]);
         }
     }else{
         exit("参数出错!\n");
     }
     do{
         $mrc = curl_multi_exec($mh,$active);
         curl_multi_select($mh);//减少CPU压力 注释掉CPU压力变大
     }while($active);
     foreach($curls as $key=>$ch){
         $html = curl_multi_getcontent($ch);
         curl_multi_remove_handle($mh,$ch);
         curl_close($ch);
         $htmls[$key] = $html;
     }
     curl_multi_close($mh);
     return $htmls;
 }

常用的get请求是通过改变url参数来实现的,又因为我们的函数是针对数据采集的。必然是分类采集,所以网址类似于这种:

http://www.baidu.com/s?wd=shili&pn=0&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=10&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=20&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=30&ie=utf-8

http://www.baidu.com/s?wd=shili&pn=50&ie=utf-8

上面五个页面是很有规律的,改变的仅仅是pn的值。

$urls = array();
 for($i=1; $i<=5; $i++){
     $urls[] = 'http://www.baidu.com/s?wd=shili&pn='.(($i-1)*10).'&ie=utf-8';
 }
 $option[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0';
 $htmls = get_htmls($urls,$option);
 foreach($htmls as $html){
     echo $html;//这里得到html 就可以进行数据处理了
 }

模拟常用的post请求:

写一个post.php文件如下:

 if(isset($_POST['username']) && isset($_POST['password'])){
     echo '用户名是: '.$_POST['username'].' 密码是: '.$_POST['password'];
 }else{
     echo '请求错误!';
 }

然后调用如下:
$url = 'http://localhost/yourpath/post.php';//这里是你的路径
 $options = array();
 for($i=1; $i<=5; $i++){
     $option[CURLOPT_POSTFIELDS] = 'username=user'.$i.'&password=pass'.$i;
     $options[] = $option;
 }
 $htmls = get_htmls($url,$options,'post');
 foreach($htmls as $html){
     echo $html;//这里得到html 就可以进行数据处理了
 }

这样这个get_htmls函数也基本能实现一些数据采集的功能了

今天分享就到这里 写的不好的 讲得不清楚的 请多多指教

PHP 相关文章推荐
一个从别的网站抓取信息的例子(域名查询)
Oct 09 PHP
PHP实现绘制3D扇形统计图及图片缩放实例
Oct 01 PHP
php判断输入是否是纯数字,英文,汉字的方法
Mar 05 PHP
php项目开发中用到的快速排序算法分析
Jun 25 PHP
Yii实现Command任务处理的方法详解
Jul 14 PHP
你不知道的文件上传漏洞php代码分析
Sep 29 PHP
php+mysql+ajax实现单表多字段多关键词查询的方法
Apr 15 PHP
php实现基于pdo的事务处理方法示例
Jul 21 PHP
PHP中TP5 上传文件的实例详解
Jul 31 PHP
PHP explode()函数用法讲解
Feb 15 PHP
php中对象引用和复制实例分析
Aug 14 PHP
PHP常用函数之根据生日计算年龄功能示例
Oct 21 PHP
基于curl数据采集之单页面采集函数get_html的使用
Apr 28 #PHP
基于php上传图片重命名的6种解决方法的详细介绍
Apr 28 #PHP
PHP基础学习之流程控制的实现分析
Apr 28 #PHP
PHP基础之运算符的使用方法
Apr 28 #PHP
PHP数据类型之整数类型、浮点数的介绍
Apr 28 #PHP
PHP数据类型之布尔型的介绍
Apr 28 #PHP
PHP中最容易忘记的一些知识点总结
Apr 28 #PHP
You might like
PHP 和 XML: 使用expat函数(三)
2006/10/09 PHP
分享一段PHP制作的中文拼音首字母工具类
2014/12/11 PHP
php判断两个日期之间相差多少个月份的方法
2015/06/18 PHP
php获取汉字拼音首字母的方法
2015/10/21 PHP
利用php生成验证码
2017/02/23 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
extjs fckeditor集成代码
2009/05/10 Javascript
Firefox outerHTML实现代码
2009/06/04 Javascript
javascript预加载图片、css、js的方法示例介绍
2013/10/14 Javascript
cookie中的path与domain属性详解
2013/12/18 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
JavaScript获取文本框内选中文本的方法
2015/02/20 Javascript
js禁止页面刷新与后退的方法
2015/06/08 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
jQuery 跨域访问解决原理案例详解
2016/07/09 Javascript
angularJs中datatable实现代码
2017/06/03 Javascript
Angular实现的简单定时器功能示例
2017/12/28 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
2018/08/31 Javascript
javascript事件监听与事件委托实例详解
2019/08/16 Javascript
[04:44]DOTA2 2017全国高校联赛视频回顾
2017/08/21 DOTA
[01:35]2018完美盛典章节片——共竞
2018/12/17 DOTA
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
Python使用内置json模块解析json格式数据的方法
2017/07/20 Python
Python3.5.3下配置opencv3.2.0的操作方法
2018/04/02 Python
python实践项目之监控当前联网状态详情
2019/05/23 Python
Django集成CAS单点登录的方法示例
2019/06/10 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
Python 中的pygame安装与配置教程详解
2020/02/10 Python
Python高并发解决方案实现过程详解
2020/07/31 Python
在HTML5 Canvas中放入图片和保存为图片的方法
2014/05/03 HTML / CSS
英国灯具和灯泡网上商店:Lights.co.uk
2018/02/02 全球购物
美国传奇滑手Paul Rodriguez创办的街头滑板品牌:Primitive Skateboarding
2019/10/29 全球购物
电子商务个人自荐信
2013/12/12 职场文书
大学新生欢迎词
2014/01/10 职场文书
信息专业大学生自我评价分享
2014/01/17 职场文书
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android