基于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 随机生成10位字符代码
Mar 26 PHP
PHP中文分词的简单实现代码分享
Jul 17 PHP
php多层数组与对象的转换实例代码
Aug 05 PHP
php对二维数组按指定键值key排序示例代码
Nov 26 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
Jun 13 PHP
mantis安装、配置和使用中的问题小结
Jul 14 PHP
php判断文件夹是否存在不存在则创建
Apr 09 PHP
详解PHP归并排序的实现
Oct 18 PHP
PHP实现RTX发送消息提醒的实例代码
Jan 03 PHP
利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
Jun 27 PHP
基于php流程控制语句和循环控制语句(讲解)
Oct 23 PHP
laravel 执行迁移回滚示例
Oct 23 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
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
javascript 节点遍历函数
2010/03/28 Javascript
从jQuery.camelCase()学习string.replace() 函数学习
2011/09/13 Javascript
有关于JS辅助函数inherit()的问题
2013/04/07 Javascript
jQuery中last()方法用法实例
2015/01/06 Javascript
javascript中对Date类型的常用操作小结
2016/05/19 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
2016/08/15 Javascript
学习 NodeJS 第八天:Socket 通讯实例
2016/12/21 NodeJs
nest.js 使用express需要提供多个静态目录的操作方法
2019/10/24 Javascript
vue - vue.config.js中devServer配置方式
2019/10/30 Javascript
vue 检测用户上传图片宽高的方法
2020/02/06 Javascript
vue实现循环滚动列表
2020/06/30 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
2020/07/18 Javascript
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
Python中pygame的mouse鼠标事件用法实例
2015/11/11 Python
图文讲解选择排序算法的原理及在Python中的实现
2016/05/04 Python
利用Python的turtle库绘制玫瑰教程
2019/11/23 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
2020/03/18 Python
Python中的None与 NULL(即空字符)的区别详解
2020/09/24 Python
CSS3之2D与3D变换的实现方法
2019/01/28 HTML / CSS
美国顶级户外凉鞋品牌:Chacos
2017/03/27 全球购物
奥地利领先的在线药房:SHOP APOTHEKE
2019/10/07 全球购物
nohup的用法
2014/08/10 面试题
施工安全协议书
2013/12/11 职场文书
求职简历中自我评价
2014/01/28 职场文书
工作违纪检讨书
2014/02/17 职场文书
客户接待方案
2014/02/26 职场文书
爱祖国演讲稿
2014/05/04 职场文书
卫生院健康教育实施方案
2014/06/07 职场文书
党课心得体会范文
2014/09/09 职场文书
三方股东合作协议书范本
2014/09/28 职场文书
一年级语文上册复习计划
2015/01/17 职场文书
社会实践单位意见
2015/06/05 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
SQL语法CONSTRAINT约束操作详情
2022/01/18 MySQL
如何优化vue打包文件过大
2022/04/13 Vue.js