php curl_multi_init 多线程

站长 2周前 访问:32 评论:0 关注:0

php 经常被抱怨没有多线程,做爬虫很吃力,其实一直一个误解,curl_multi_init 就是一个很好的多线程发方法。
配合 domDocment 类可以很完美的实现爬虫功能,下面是例子代码,并不包含解析html

<?php
set_time_limit(0);
ob_start();
$urls = array(   
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',    
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/',   
'http://www.sohu.com/',   
'http://www.163.com/',
'http://www.zhihu.com/',
'http://www.xunlei.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.jianshu.com/',
'http://www.xiachufang.com/',
'http://www.163.com/',
'http://www.gelonghui.com/',
'http://www.jianshu.com/',
'http://www.sina.com.cn/'
);   

//生命一个计算脚本运行时间的类
class Timer{
private $startTime = 0; //保存脚本开始执行时的时间(以微秒的形式保存)
private $stopTime = 0; //保存脚本结束执行时的时间(以微秒的形式保存)

//在脚本开始处调用获取脚本开始时间的微秒值
function start(){
$this->startTime = microtime(true); //将获取的时间赋值给成员属性$startTime
}
//脚本结束处嗲用脚本结束的时间微秒值
function stop(){
$this->stopTime = microtime(true); //将获取的时间赋给成员属性$stopTime
}
//返回同一脚本中两次获取时间的差值
function spent(){
//计算后4舍5入保留4位返回
return round(($this->stopTime-$this->startTime),4);
}
}

$timer= new Timer(); 
$timer->start(); //在脚本文件开始执行时调用这个方法

ob_end_clean();
//$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);  // 设置不将爬取代码写到浏览器,而是转化为字符串   
  echo $i;
  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.$i);  // 将字符串写入文件。当然,也可以不写入文件,比如存入数据库  
   file_put_contents("file/".$i.".txt",$data);
   echo $url."<br/>";
   ob_flush();
   flush(); 
   //usleep(200000);
} // 获得数据变量,并写入文件   

foreach ($urls as $i => $url) {   
  curl_multi_remove_handle($mh,$conn[$i]);   
  curl_close($conn[$i]);   
}   

curl_multi_close($mh);   
//fclose($st);  
$timer->stop(); //在脚本文件结束处调用这个方法

echo "run time -> ".$timer->spent()."</b>";
?>

来源:https://www.jianshu.com/p/ebafc55c892b


评论

还没有人评论 ~

公告