>  기사  >  백엔드 개발  >  PHP는 컬을 기반으로 멀티스레드 크롤링을 구현합니다.

PHP는 컬을 기반으로 멀티스레드 크롤링을 구현합니다.

墨辰丷
墨辰丷원래의
2018-06-08 18:01:423593검색

이 글은 주로 컬 기반의 멀티스레드 크롤링을 구현하기 위한 PHP를 소개합니다. 관심 있는 친구들이 참고하면 도움이 될 것입니다.

PHP는 Curl을 사용하여 브라우저를 시뮬레이션하여 GET, POST 요청 등을 보내는 등 다양한 파일 전송 작업을 완료할 수 있습니다. 그러나 PHP 언어 자체는 멀티스레딩을 지원하지 않기 때문에 크롤러 프로그램 개발 효율성이 높지 않습니다. , 따라서 Curl 멀티 기능을 사용해야 하는 경우가 많습니다. 이 기능은 웹 페이지의 동시 멀티 스레드 크롤링 또는 파일 다운로드를 달성하기 위해 여러 URL 주소에 대한 동시 멀티 스레드 액세스를 구현합니다

코드는 다음과 같습니다.

<?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;http://www.jb51.net/&#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;http://www.jb51.net/&#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;http://www.jb51.net/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;http://www.jb51.net/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);

요약: 위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되었으면 좋겠습니다.

관련 추천:

php 파일 업로드 관리 시스템

PHP 이메일 전송 사례

php 파일 업로드 관리 시스템

위 내용은 PHP는 컬을 기반으로 멀티스레드 크롤링을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.