基于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 相关文章推荐
使用 MySQL 开始 PHP 会话
Dec 21 PHP
php 进度条实现代码
Mar 10 PHP
提高PHP编程效率 引入缓存机制提升性能
Feb 15 PHP
Php Image Resize图片大小调整的函数代码
Jan 17 PHP
PHP下判断网址是否有效的代码
Oct 08 PHP
php上传大文件失败的原因及应对策略
Oct 20 PHP
PHP与SQL语句常用大全
Dec 10 PHP
PHP正则匹配日期和时间(时间戳转换)的实例代码
Dec 14 PHP
PHP缩略图生成和图片水印制作
Jan 07 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
Aug 29 PHP
PHP获取MySQL执行sql语句的查询时间方法
Aug 21 PHP
详解PHP实现支付宝小程序用户授权的工具类
Dec 25 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
PHP5常用函数列表(分享)
2013/06/07 PHP
JavaScript 学习笔记(十六) js事件
2010/02/01 Javascript
JavaScript Eval 函数使用
2010/03/23 Javascript
javascript中检测变量的类型的代码
2010/12/28 Javascript
前端必备神器 Snap.svg 弹动效果
2014/11/10 Javascript
javascript正则表达式之search()用法实例
2015/01/19 Javascript
Bootstrap实现下拉菜单效果
2016/04/29 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
Ext JS动态加载JavaScript创建窗体的方法
2016/06/23 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
Three.js实现简单3D房间布局
2018/12/30 Javascript
Easyui 去除jquery-easui tab页div自带滚动条的方法
2019/05/10 jQuery
JS中比Switch...Case更优雅的多条件判断写法
2019/09/05 Javascript
jQuery Raty星级评分插件使用方法实例分析
2019/11/25 jQuery
京东优选小程序的实现代码示例
2020/02/25 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
解决idea开发遇到javascript动态添加html元素时中文乱码的问题
2020/09/29 Javascript
Python的lambda匿名函数的简单介绍
2013/04/25 Python
Python查询IP地址归属完整代码
2017/06/21 Python
Python实现比较扑克牌大小程序代码示例
2017/12/06 Python
python调用opencv实现猫脸检测功能
2019/01/15 Python
Python generator生成器和yield表达式详解
2019/08/08 Python
python制作英语翻译小工具代码实例
2019/09/09 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
Python数据正态性检验实现过程
2020/04/18 Python
Python figure参数及subplot子图绘制代码
2020/04/18 Python
详解Python中的编码问题(encoding与decode、str与bytes)
2020/09/30 Python
HTML5 和小程序实现拍照图片旋转、压缩和上传功能
2018/10/08 HTML / CSS
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
安全员岗位职责
2013/11/11 职场文书
物流毕业生个人的自我评价
2014/02/13 职场文书
高中军训第一天感言
2014/03/06 职场文书
医疗纠纷协议书
2014/04/16 职场文书
springboot读取resources下文件的方式详解
2022/06/21 Java/Android