基于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截取字符串并保留完整xml标签的函数代码
Feb 06 PHP
基于php无限分类的深入理解
Jun 02 PHP
php+mysqli使用面向对象方式查询数据库实例
Jan 29 PHP
PHP中foreach()用法汇总
Jul 02 PHP
ThinkPHP控制器详解
Jul 27 PHP
php开发工具有哪五款
Nov 09 PHP
Linux+Nginx+MySQL下配置论坛程序Discuz的基本教程
Dec 23 PHP
详解WordPress中分类函数wp_list_categories的使用
Jan 04 PHP
利用PHP自动生成印有用户信息的名片
Aug 01 PHP
php实现的简单数据库操作Model类
Nov 16 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
Yii Framework框架开发微信公众平台示例
Apr 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
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
2014/12/18 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
php如何计算两坐标点之间的距离
2018/12/29 PHP
PHP实现获取ip地址的5种方法,以及插入用户登录日志操作示例
2019/02/28 PHP
CSDN轮换广告图片轮换效果
2007/03/27 Javascript
基于jquery的二级联动菜单实现代码
2011/04/25 Javascript
对比分析json及XML
2014/11/28 Javascript
js对象基础实例分析
2015/01/13 Javascript
js实现动态加载脚本的方法实例汇总
2015/11/02 Javascript
AngularJS使用ngMessages进行表单验证
2015/12/27 Javascript
JS 清除字符串数组中,重复元素的实现方法
2016/05/24 Javascript
Bootstrap基本组件学习笔记之按钮组(8)
2016/12/07 Javascript
Vue 去除路径中的#号
2018/04/19 Javascript
JavaScript 2018 中即将迎来的新功能
2018/09/21 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析
2019/12/02 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
2020/01/21 Javascript
分享一款超好用的JavaScript 打包压缩工具
2020/04/26 Javascript
vue 接口请求地址前缀本地开发和线上开发设置方式
2020/08/13 Javascript
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
2019/04/10 Python
Linux上使用Python统计每天的键盘输入次数
2019/04/17 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
matplotlib.pyplot.plot()参数使用详解
2020/07/28 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
Django中和时区相关的安全问题详解
2020/10/12 Python
python time()的实例用法
2020/11/03 Python
学校安全教育制度
2014/01/31 职场文书
2015暑期工社会实践报告
2015/07/13 职场文书
安全教育培训制度
2015/08/06 职场文书
毕业设计工作总结
2015/08/14 职场文书
大学生奶茶店创业计划书
2019/06/25 职场文书
导游词之山海关
2019/12/10 职场文书
MySQL系列之三 基础篇
2021/07/02 MySQL
Linux中各个目录的作用与内容
2022/06/28 Servers