基于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 相关文章推荐
PHP脚本数据库功能详解(上)
Oct 09 PHP
海河写的 Discuz论坛帖子调用js的php代码
Aug 23 PHP
smarty模板引擎基础知识入门
Mar 30 PHP
discuz图片顺序混乱解决方案
Jul 29 PHP
php强制下载文件函数
Aug 24 PHP
php curl 模拟登录并获取数据实例详解
Dec 22 PHP
Yii2实现自定义独立验证器的方法
May 05 PHP
php实例化一个类的具体方法
Sep 19 PHP
浅谈Laravel中的三种中间件的作用
Oct 13 PHP
浅谈Laravel模板实体转义带来的坑
Oct 22 PHP
再谈Yii Framework框架中的事件event原理与应用
Apr 07 PHP
aec加密 php_php aes加密解密类(兼容php5、php7)
Mar 14 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
我的论坛源代码(五)
2006/10/09 PHP
yii实现model添加默认值的方法(2种方法)
2016/01/06 PHP
PHP实现链式操作的原理详解
2016/09/16 PHP
Javascript 去除数组的重复元素
2010/05/04 Javascript
精通Javascript系列之数值计算
2011/06/07 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
2020/09/13 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
20行JS代码实现粘贴板复制功能
2018/02/06 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
微信小程序和H5页面间相互跳转代码实例
2019/09/19 Javascript
layui按条件隐藏表格列的实例
2019/09/19 Javascript
layui添加动态菜单与选项卡 AJAX请求的例子
2019/09/25 Javascript
jquery获取input输入框中的值
2019/11/13 jQuery
VUE-ElementUI 自定义Loading图操作
2020/11/11 Javascript
[43:14]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
Python中的defaultdict模块和namedtuple模块的简单入门指南
2015/04/01 Python
Python的Flask框架中web表单的教程
2015/04/20 Python
Django框架模板注入操作示例【变量传递到模板】
2018/12/19 Python
Python学习笔记之迭代器和生成器用法实例详解
2019/08/08 Python
python向图片里添加文字
2019/11/26 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
Python ini文件常用操作方法解析
2020/04/26 Python
浅谈优化Django ORM中的性能问题
2020/07/09 Python
澳大利亚最受欢迎的美发和美容在线商店:Catwalk
2018/12/12 全球购物
逻辑链路控制协议
2016/10/01 面试题
初中生期末考试的自我评价
2013/12/17 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
经贸日语专业个人求职信范文
2014/04/29 职场文书
政治思想表现评语
2014/05/04 职场文书
签约仪式策划方案
2014/06/02 职场文书
2015年人力资源工作总结
2015/04/08 职场文书
乒乓球比赛通知
2015/04/27 职场文书
2015大学生入党个人自传
2015/06/26 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python