基于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 快速生成 Flash 动画的方法
Mar 06 PHP
获取PHP警告错误信息的解决方法
Jun 03 PHP
PHP设计模式之代理模式的深入解析
Jun 13 PHP
PHP函数addslashes和mysql_real_escape_string的区别
Apr 22 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
Jun 12 PHP
php实现上传图片文件代码
Jul 19 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
Aug 23 PHP
PHP使用token防止表单重复提交的方法
Apr 07 PHP
PHP获取网站中各文章的第一张图片的代码示例
May 20 PHP
PHP常用算法和数据结构示例(必看篇)
Mar 15 PHP
PHP工厂模式的日常使用
Mar 20 PHP
Mac下关于PHP环境和扩展的安装详解
Oct 17 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
虫族 ZERG 概述
2020/03/14 星际争霸
WordPress判断用户是否登录的代码
2011/03/17 PHP
php中使用Imagick实现图像直方图的实现代码
2011/08/30 PHP
php preg_filter执行一个正则表达式搜索和替换
2012/02/27 PHP
php读取文件内容至字符串中,同时去除换行、空行、行首行尾空格(Zjmainstay原创)
2012/07/31 PHP
php header功能的使用
2013/10/28 PHP
php使用$_POST或$_SESSION[]向js函数传参
2014/09/16 PHP
Linux下编译redis和phpredis的方法
2016/04/07 PHP
laravel 自定义常量的两种方案
2019/10/14 PHP
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
js中通过split函数分割字符串成数组小例子
2013/09/21 Javascript
利用Keydown事件阻止用户输入实现代码
2014/03/11 Javascript
JavaScript获取图片的原始尺寸以宽度为例
2014/05/04 Javascript
JavaScript函数详解
2014/11/17 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
JavaScript实现的搜索及高亮显示功能示例
2017/08/14 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
python文件操作相关知识点总结整理
2016/02/22 Python
Python中if elif else及缩进的使用简述
2018/05/31 Python
python3.6的venv模块使用详解
2018/08/01 Python
基于MSELoss()与CrossEntropyLoss()的区别详解
2020/01/02 Python
利用python+request通过接口实现人员通行记录上传功能
2021/01/13 Python
世界上最大的汽车共享网站:Zipcar
2017/01/14 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
物业门卫岗位职责
2013/12/28 职场文书
七一党建活动方案
2014/01/28 职场文书
伦敦奥运会的口号
2014/06/21 职场文书
股权转让协议书
2014/12/07 职场文书
小学数学教学随笔
2015/08/14 职场文书
撤回我也能看到!教你用Python制作微信防撤回脚本
2021/06/11 Python
JavaScript中isPrototypeOf函数
2021/11/07 Javascript