• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

php curl_multi_exec()并发抓取网页内容

php 搞代码 3年前 (2022-01-23) 10次浏览 已收录 0个评论

php curl_multi_exec()并发抓取网页内容

php是个单线程的语言,于是在某方面速率比不上java这种多线程的语言,毕竟主打方面不在这里..但是php也有自己的多线程(其实是并发)方法–curl_multi_exec().

我们可以用curll来获取网页的内容(不懂curl的可以找个简单的例子来看看),但是若是同时获取多个网页的内容,速度就不太理想,这个时候curl_multi_exec()就可以发挥作用了。

下面是我在抓取优酷网内容的例子:

function async_get_url($url_array, $wait_usec = 0){    if (!is_array($url_array))        return false;                                                                                              $wait_usec = intval($wait_usec);                                                                                              $data    = array();    $handle  = array();    $running = 0;                                                                                              $mh = curl_multi_init(); // multi curl handler                                                                                              $i = 0;    foreach($url_array as $url) {        $ch = curl_init();                                                                                                  curl_setopt($ch, CURLOPT_URL, $url);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print        curl_setopt($ch, CURLOPT_TIMEOUT, 30);        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect        curl_setopt($ch, CURLOPT_MAXREDIRS, 7);                                                                                                  curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡                                                                                                  $handle[$i++] = $ch;    }                                                                                              /* 此做法就可以避免掉 CPU loading 100% 的問題 */    // 參考自: http://www.hengss.com/xueyuan/sort0362/php/info-36963.html                                                                                              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);        }    }    /*     // 感謝 Ren 指點的作法. (需要在測試一下)    // curl_multi_exec的返回值是用來返回多線程處裡時的錯誤,正常來說返回值是0,也就是說只用$mrc捕捉返回值當成判斷式的迴圈只會運行一次,而真的發生錯誤時,有拿$mrc判斷的都會變死迴圈。    // 而curl_multi_select的功能是curl發送請求後,在有回應前會一直處於等待狀態,所以不需要把它導入空迴圈,它就像是會自己做判斷&自己決定等待時間的sleep()。    /* 讀取資料 */    foreach($handle as $i => $ch) {        $content  = curl_multi_getcontent($ch);        $data[$i] = (curl_errno($ch) == 0) ? $content : false;    }                                                                                              /* 移除 handle*/    foreach($handle as $ch) {        curl_multi_remove_handle($mh, $ch);    }                                                                                              curl_multi_close($mh);                                                                                              return $data;}                                                                                          $url="http://m.youku.com/wap/";$reg1="/(.*?)<\/a>/i";//获取视频链接$reg2="/]*)\s*class=\"imgdetail\"\s*src=('|\")([^'\"]+)('|\")/i";$reg3="";$reg4= "/

.*?<\/p>/i";//获取视频标题(备选) // 创建两个cURL资源$ch1 = curl_init();$resultArray=array();//装载所有数据的数组$ch=array();//$ch2 = curl_init();// 指定URL和适当的参数curl_setopt($ch1, CURLOPT_URL,$url);curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch1, CURLOPT_HEADER, 0);$content=curl_exec($ch1);curl_close($ch1);//$content=file_get_contents($url);preg_match_all($reg1, $content,$matches);$video=$matches[0];//首页视频的链接//print_r($video);foreach ($video as $a=>$key){ $position=strpos($key, "href"); $substring=substr($key, $position+11); $pos=strpos($substring, ">"); $link=substr($substring, 0,$pos-1); $nextUrl[$a]=$url.$link;}//$url_array = array( // 'http://www.google.com', // 'http://www.baidu.com',//);//print_r($nextUrl);//print_r(async_get_url($nextUrl));//并发获取所有网页的内容$allData=async_get_url($nextUrl);foreach ($allData as $page){ //获取视频图片 preg_match_all($reg2, $page,$img); $img_arr=$img[0]; foreach ($img_arr as $arr) { $position=strpos($arr, "src"); $sub=substr($arr, $position+5); $pos=strpos($sub, "\""); $last=substr($sub, 0,$pos); } //获取视频高清点播地址 preg_match_all($reg3, $page,$vids); $video_arr=$vids[0]; $vid=$video_arr[0]; $position=strpos($vid, "href"); $v_string=substr($vid, $position+11); $pos=strpos($v_string, "\""); $add=substr($v_string, 0,$pos); $video_url=$url.$add; //获取视频的标题 preg_match_all($reg4, $page,$match); $title=$match[0]; //print_r($er); $r=serialize($title); $position=mb_strpos($r, "

"); $sub=substr($r, 0,$position); $pos=mb_strrpos($sub, ">"); $til=substr($sub, $pos+1); 本2文来*源gao($daima.com搞@代@#码(网搞gaodaima代码 //整合到一个数组 $subArray=array('image'=>$last,'video'=>$video_url,'title'=>$til); array_push($resultArray, $subArray);}echo json_encode($resultArray);

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:php curl_multi_exec()并发抓取网页内容
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址