zoukankan      html  css  js  c++  java
  • CURL PHP实现多线程抓取网页

      PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Curl Multi Functions 它可以实现并发多线程的访问多个url地址。既然 Curl Multi Function如此强大,能否用 Curl Multi Functions 来写并发多线程下载文件呢,当然可以,下面给出我的代码:

    <?php
    $urls = array(  
     'http://www.sina.com.cn/',  
     'http://www.sohu.com/',  
     'http://www.163.com/' 
    ); // 设置要抓取的页面URL  
         
    $save_to='/test.txt';   // 把抓取的代码写入该文件   
       
    $st = fopen($save_to,"a");  
    $mh = curl_multi_init();   
       
    foreach ($urls as $i => $url) {  
      $conn[$i] = curl_init($url);  
      curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");  
      curl_setopt($conn[$i], CURLOPT_HEADER ,0);  
      curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);  
      curl_setopt($conn[$i], CURLOPT_FILE,$st); // 设置将爬取的代码写入文件  
      curl_multi_add_handle ($mh,$conn[$i]);  
    } // 初始化  
         
    do {  
      curl_multi_exec($mh,$active);  
    } while ($active);  // 执行  
         
    foreach ($urls as $i => $url) {  
      curl_multi_remove_handle($mh,$conn[$i]);  
      curl_close($conn[$i]);  
    } // 结束清理  
         
    curl_multi_close($mh);  
    fclose($st);
    ?>

    代码2:将获得的代码先放入变量,再写入某个文件

    <?php
    $urls = array(  
     'http://www.sina.com.cn/',  
     'http://www.sohu.com/',  
     'http://www.163.com/' 
    );  
       
    $save_to='/test.txt';   // 把抓取的代码写入该文件  
    $st = fopen($save_to,"a");  
       
    $mh = curl_multi_init();  
    foreach ($urls as $i => $url) {  
      $conn[$i] = curl_init($url);  
      curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");  
      curl_setopt($conn[$i], CURLOPT_HEADER ,0);  
      curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);  
      curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true);  // 设置不将爬取代码写到浏览器,而是转化为字符串  
      curl_multi_add_handle ($mh,$conn[$i]);  
    }  
       
    do {  
      curl_multi_exec($mh,$active);  
    } while ($active);  
         
    foreach ($urls as $i => $url) {  
      $data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串  
      fwrite($st,$data);  // 将字符串写入文件。当然,也可以不写入文件,比如存入数据库  
    } // 获得数据变量,并写入文件  
       
    foreach ($urls as $i => $url) {  
      curl_multi_remove_handle($mh,$conn[$i]);  
      curl_close($conn[$i]);  
    }  
       
    curl_multi_close($mh);  
    fclose($st); 
    ?>

    http://www.cnblogs.com/jyginger/archive/2010/07/20/1781516.html

    // 上面的do是有问题的,那样写会出现错误
    // 更改的do循环start
    do {
      $mrc = curl_multi_exec($mh,$active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
       
    while ($active and $mrc == CURLM_OK) {
      if (curl_multi_select($mh) != -1) {
        do {
          $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
      }
    }
    // 更改的do循环 end
    因为$active要等全部url数据接受完毕才变成false,所以这里用到了curl_multi_exec的返回值判断是否还有数据,当有数据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。这里的好处就是CPU的无谓消耗没有了。

    http://blog.csdn.net/oyd/article/details/1820615

  • 相关阅读:
    springBoot从入门到源码分析
    MQ疑难杂症小记
    dubbo学习思路梳理
    Zookeeper
    分布式系统理论概述
    mysql,存储引擎,事务,锁,慢查询,执行计划分析,sql优化
    tomcat学习步骤,附带打破双亲委派模型企业应用实战
    使用UtraISO为U盘制作系统启动盘
    洛谷P3369 splay或treap
    gym 101982 B题 Coprime Integers
  • 原文地址:https://www.cnblogs.com/phpor/p/3595513.html
Copyright © 2011-2022 走看看