基于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 相关文章推荐
BBS(php &amp; mysql)完整版(四)
Oct 09 PHP
一贴学会PHP 新手入门教程
Aug 03 PHP
php eval函数用法 PHP中eval()函数小技巧
Oct 31 PHP
如何在smarty中增加类似foreach的功能自动加载数据
Jun 26 PHP
用PHP来计算某个目录大小的方法
Apr 01 PHP
Yii 快速,安全,专业的PHP框架
Sep 03 PHP
php简单图像创建入门实例
Jun 10 PHP
PHP中使用array函数新建一个数组
Nov 19 PHP
如何判断php mysqli扩展类是否开启
Dec 24 PHP
使用PHP json_decode可能遇到的坑与解决方法
Aug 03 PHP
php实现多站点共用session实现单点登录的方法详解
Sep 18 PHP
php弹出提示框的是实例写法
Sep 26 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
YB217、YB235、YB400浅听
2021/03/02 无线电
php 深入理解strtotime函数的使用详解
2013/05/23 PHP
PHP 获取 ping 时间的实现方法
2017/09/29 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
javascript背投广告代码的完善
2008/04/08 Javascript
最简单的jQuery程序 入门者学习
2009/07/09 Javascript
DWZ刷新dialog解决方法
2013/03/03 Javascript
Javascript中的默认参数详解
2014/10/22 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
2015/03/14 Javascript
javascript中scrollTop详解
2015/04/13 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
js中split()方法得到的数组长度问题
2018/07/19 Javascript
JavaScript使用小插件实现倒计时的方法讲解
2019/03/11 Javascript
js如何获取访问IP、地区、当前操作浏览器
2019/07/23 Javascript
vue 对axios get pust put delete封装的实例代码
2020/01/05 Javascript
vue 使用 sortable 实现 el-table 拖拽排序功能
2020/12/26 Vue.js
python操作redis的方法
2015/07/07 Python
基于python3 OpenCV3实现静态图片人脸识别
2018/05/25 Python
python数据批量写入ScrolledText的优化方法
2018/10/11 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
python反编译学习之字节码详解
2019/05/19 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
flask项目集成swagger的方法
2020/12/09 Python
好的自荐信的要求
2013/10/30 职场文书
毕业生文员求职信
2013/11/03 职场文书
行政文员岗位职责
2013/11/08 职场文书
淘宝客服自我总结鉴定
2014/01/25 职场文书
婚纱摄影师求职信
2014/03/07 职场文书
党员志愿者活动总结
2014/06/26 职场文书
化学教育专业自荐信
2014/07/04 职场文书
动物科学专业求职信
2014/07/27 职场文书
Windows下redis下载、redis安装及使用教程
2021/06/02 Redis
Java并发编程之Executor接口的使用
2021/06/21 Java/Android