> 백엔드 개발 > PHP 튜토리얼 > 다중 스레드 크롤링을 달성하기 위해 PHP와 컬의 결합

다중 스레드 크롤링을 달성하기 위해 PHP와 컬의 결합

高洛峰
풀어 주다: 2023-03-03 19:50:01
원래의
908명이 탐색했습니다.

멀티 스레드 크롤링을 달성하기 위해 컬과 PHP를 결합

<?php
/*
curl 多线程抓取
*/
 /**
   * curl 多线程
   *
   * @param array $array 并行网址
   * @param int $timeout 超时时间
   * @return array
   */
 function Curl_http($array,$timeout){
 $res = array();
 $mh = curl_multi_init();//创建多个curl语柄
 $startime = getmicrotime();
 foreach($array as $k=>$url){
  $conn[$k]=curl_init($url);
 
    curl_setopt($conn[$k], CURLOPT_TIMEOUT, $timeout);//设置超时时间
    curl_setopt($conn[$k], CURLOPT_USERAGENT, &#39;Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
    curl_setopt($conn[$k], CURLOPT_MAXREDIRS, 7);//HTTp定向级别
    curl_setopt($conn[$k], CURLOPT_HEADER, 0);//这里不要header,加块效率
    curl_setopt($conn[$k], CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
    curl_setopt($conn[$k],CURLOPT_RETURNTRANSFER,1);
    curl_multi_add_handle ($mh,$conn[$k]);
 }
 //防止死循环耗死cpu 这段是根据网上的写法
 do {
  $mrc = curl_multi_exec($mh,$active);//当无数据,active=true
 } while ($mrc == CURLM_CALL_MULTI_PERFORM);//当正在接受数据时
 while ($active and $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true
  if (curl_multi_select($mh) != -1) {
  do {
   $mrc = curl_multi_exec($mh, $active);
  } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
 }
 
 foreach ($array as $k => $url) {
   curl_error($conn[$k]);
    $res[$k]=curl_multi_getcontent($conn[$k]);//获得返回信息
    $header[$k]=curl_getinfo($conn[$k]);//返回头信息
    curl_close($conn[$k]);//关闭语柄
    curl_multi_remove_handle($mh , $conn[$k]);  //释放资源
 }
 
 curl_multi_close($mh);
 $endtime = getmicrotime();
 $diff_time = $endtime - $startime;
 
 return array(&#39;diff_time&#39;=>$diff_time,
   &#39;return&#39;=>$res,
   &#39;header&#39;=>$header
   );
 
 }
 //计算当前时间
 function getmicrotime() {
   list($usec, $sec) = explode(" ",microtime());
   return ((float)$usec + (float)$sec);
 }
 
 //测试一下,curl 三个网址
 $array = array(
  "http://www.weibo.com/",
  "http://www.renren.com/",
  "http://www.qq.com/"
  );
 $data = Curl_http($array,&#39;10&#39;);//调用
 var_dump($data);//输出
//如果POST的数据大于1024字节,curl并不会直接就发起POST请求
//发送请求时,header中包含一个空的Expect。curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:"));
?>
로그인 후 복사

몇 가지 예를 더 살펴보겠습니다

(1) 다음 단락 코드는 여러 개의 URL을 캡처한 후 캡처된 URL의 페이지 코드를 지정된 파일

$urls = array(
&#39;//m.sbmmt.com/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$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) 다음 단락 얻은 코드를 먼저 변수에 넣은 다음 얻은 내용을 지정된 파일에 쓰는 것을 제외하면 코드는 위와 거의 동일합니다.

$urls = array(
&#39;//m.sbmmt.com/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$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);
로그인 후 복사

(3) 다음 코드는 PHP의 Curl 함수를 사용하여 동시 멀티스레드 파일 다운로드를 구현합니다.

$urls=array(
 &#39;//m.sbmmt.com/5w.zip&#39;,
 &#39;http://www.jb51.net/5w.zip&#39;,
 &#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
 $g=$save_to.basename($url);
 if(!is_file($g)){
   $conn[$i]=curl_init($url);
   $fp[$i]=fopen($g,"w");
   curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
   curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
   curl_setopt($conn[$i],CURLOPT_HEADER ,0);
   curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
   curl_multi_add_handle($mh,$conn[$i]);
 }
}
do{
 $n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
 curl_multi_remove_handle($mh,$conn[$i]);
 curl_close($conn[$i]);
 fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
 &#39;//m.sbmmt.com/5w.zip&#39;,
 &#39;//m.sbmmt.com/5w.zip&#39;,
 &#39;//m.sbmmt.com/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
 $g=$save_to.basename($url);
 if(!is_file($g)){
   $conn[$i]=curl_init($url);
   $fp[$i]=fopen($g,"w");
   curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
   curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
   curl_setopt($conn[$i],CURLOPT_HEADER ,0);
   curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
   curl_multi_add_handle($mh,$conn[$i]);
 }
}
do{
 $n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
 curl_multi_remove_handle($mh,$conn[$i]);
 curl_close($conn[$i]);
 fclose($fp[$i]);
}
curl_multi_close($mh);
로그인 후 복사

위 내용이 이 글입니다. 모두 마음에 드셨으면 좋겠습니다.

멀티 스레드 크롤링을 달성하기 위해 컬과 결합된 PHP와 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿