• curl数据采集系列之多页面并行采集函数get_htmls


    用第一篇的get_html()实现简单的数据采集,由于是一个一个执行才采集数据的传输时间就会是所有页面下载的总时长,一个页面假设1秒,那么10个页面就是10秒了。所幸curl还提供了并行处理的功能。

    要写一个并行采集的函数,先要了解要采集什么样的页面,对采集的页面用什么请求,才能写出一个相对常用的函数。 

     

    功能需求分析:

    返回什么? 

    当然每一个页面的html集合成的数组

    传递什么参数? 

    编写get_html()时,我们知道了可以用options数组来传递更多的curl参数,那么多页面同时采集函数的编写这种特性也得保留下来。

    什么类型的参数?

    无论是请求网页HTML,还是调用互联网api接口,getpost传递参数总是请求同一个页面或者接口,只是参数不同罢了。那么参数的类型是:

     

    get_htmls($url,$options);

     

    $url string

     

    $options,是一个二维数组,每一个页面的参数为一个数组。

     

    这样的话,貌似解决了问题。但是我找遍了curl的手册都没有看到get的参数传递在什么地方,所以只能$url 是数组的形式传递并且增加一个method参数

     

     

     

    函数的原型就定下来了get_htmls($urls,$options = array, $method = ‘get’);代码如下:

     

     1 function get_htmls($urls, $options = array(), $method = 'get'){
     2     $mh = curl_multi_init();
     3     if($method == 'get'){//get方式传值 最常用
     4         foreach($urls as $key=>$url){
     5             $ch = curl_init($url);
     6             $options[CURLOPT_RETURNTRANSFER] = true;
     7             $options[CURLOPT_TIMEOUT] = 5;
     8             curl_setopt_array($ch,$options);
     9             $curls[$key] = $ch;
    10             curl_multi_add_handle($mh,$curls[$key]);
    11         }
    12     }elseif($method == 'post'){//post方式传值 
    13         foreach($options as $key=>$option){
    14             $ch = curl_init($urls);
    15             $option[CURLOPT_RETURNTRANSFER] = true;
    16             $option[CURLOPT_TIMEOUT] = 5;
    17             $option[CURLOPT_POST] = true;
    18             curl_setopt_array($ch,$option);
    19             $curls[$key] = $ch;
    20             curl_multi_add_handle($mh,$curls[$key]);
    21         }
    22     }else{
    23         exit("参数出错!\n");
    24     }
    25     do{
    26         $mrc = curl_multi_exec($mh,$active);
    27         curl_multi_select($mh);//减少CPU压力 注释掉CPU压力变大
    28     }while($active);
    29     foreach($curls as $key=>$ch){
    30         $html = curl_multi_getcontent($ch);
    31         curl_multi_remove_handle($mh,$ch);
    32         curl_close($ch);
    33         $htmls[$key] = $html;
    34     }
    35     curl_multi_close($mh);
    36     return $htmls;
    37 }

     

    常用的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的值。

     

    1 $urls = array();
    2 for($i=1; $i<=5; $i++){
    3     $urls[] = 'http://www.baidu.com/s?wd=shili&pn='.(($i-1)*10).'&ie=utf-8';
    4 }
    5 $option[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0';
    6 $htmls = get_htmls($urls,$option);
    7 foreach($htmls as $html){
    8     echo $html;//这里得到html 就可以进行数据处理了
    9 }

     

    模拟常用的post请求:

    写一个post.php文件如下:

     

    1 if(isset($_POST['username']) && isset($_POST['password'])){
    2     echo '用户名是: '.$_POST['username'].' 密码是: '.$_POST['password'];
    3 }else{
    4     echo '请求错误!';
    5 }

     

    然后调用如下:

     1 $url = 'http://localhost/yourpath/post.php';//这里是你的路径
     2 $options = array();
     3 for($i=1; $i<=5; $i++){
     4     $option[CURLOPT_POSTFIELDS] = 'username=user'.$i.'&password=pass'.$i;
     5     $options[] = $option;
     6 }
     7 $htmls = get_htmls($url,$options,'post');
     8 foreach($htmls as $html){
     9     echo $html;//这里得到html 就可以进行数据处理了
    10 }

    这样这个get_htmls函数也基本能实现一些数据采集的功能了

    现在数据都采集到了本地 那么下一篇就应该讲怎么样处理得到的html了

    今天分享就到这里 写的不好的 讲得不清楚的 请多多指教

     

     

     

     

  • 相关阅读:
    前端小功能: 绘制多边形,并判断某个点是否在区域内
    Java设计模式-模板设计模式
    Java设计模式-工厂设计模式
    Java设计模式-单例设计模式
    Java简单的去重算法
    layui时间插件实现动态限制可选时间范围和统计时间间隔
    百度地图坐标只加载可视范围内的坐标
    百度地图创建删除单个坐标
    百度地图加载海量点
    创建百度地图
  • 原文地址:https://www.cnblogs.com/yanghaoinbeijing/p/2976007.html
Copyright © 2020-2023  润新知