基于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基础知识:类与对象(5) static
Dec 13 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
Oct 26 PHP
PHP常用的小程序代码段
Nov 14 PHP
PHP实现文件上传和多文件上传
Dec 24 PHP
php实现简单爬虫的开发
Mar 28 PHP
php ucwords() 函数将字符串中每个单词的首字符转换为大写(实现代码)
May 12 PHP
php获取当前月与上个月月初及月末时间戳的方法
Dec 05 PHP
php类自动装载、链式操作、魔术方法实现代码
Jul 23 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
Sep 30 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
PHP的mysqli_thread_id()函数讲解
Jan 24 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
Apr 04 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
php中实现简单的ACL 完结篇
2011/09/07 PHP
PHP 代码规范小结
2012/03/08 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
解析file_get_contents模仿浏览器头(user_agent)获取数据
2013/06/27 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
JavaScript中Object和Function的关系小结
2009/09/26 Javascript
javascript中直接引用Microsoft的COM生成Word
2014/01/20 Javascript
jQuery实现HTML5 placeholder效果实例
2014/12/09 Javascript
跟我学习javascript的var预解析与函数声明提升
2015/11/16 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
2017/02/12 Javascript
纯JS实现简单的日历
2017/06/26 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
webpack+vue+express(hot)热启动调试简单配置方法
2018/09/19 Javascript
解决vue单页面应用打包后相对路径、绝对路径相关问题
2020/08/14 Javascript
原生js实现拖拽移动与缩放效果
2020/08/24 Javascript
删除目录下相同文件的python代码(逐级优化)
2012/05/25 Python
python实现文件名批量替换和内容替换
2014/03/20 Python
python实现图像识别功能
2018/01/29 Python
python学习入门细节知识点
2018/03/29 Python
用Python PIL实现几个简单的图片特效
2019/01/18 Python
python列表每个元素同增同减和列表元素去空格的实例
2019/07/20 Python
Python实现多线程/多进程的TCP服务器
2019/09/03 Python
Django框架ORM数据库操作实例详解
2019/11/07 Python
python 上下文管理器及自定义原理解析
2019/11/19 Python
解决python图像处理图像赋值后变为白色的问题
2020/06/04 Python
python中的测试框架
2020/11/13 Python
英国婴儿及儿童产品商店:TigerParrot
2019/03/04 全球购物
大学生个人事迹材料
2014/01/21 职场文书
遗体告别仪式答谢词
2014/01/23 职场文书
欢送退休感言
2014/02/08 职场文书
售后客服个人自我评价
2014/09/14 职场文书
优秀学生干部事迹材料
2014/12/24 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
NodeJs使用webpack打包项目的方法详解
2022/02/28 NodeJs