PHP 中 curl_init() 单线程和 curl_multi_init() 多线程抓取页面的速度比较

学习笔记 马富天 2016-10-12 11:15:23 86 0

【摘要】curl_init() 处理事物是单线程模式,如果需要对事务处理走多线程模式,那么 php 里提供了一个函数 curl_multi_init() 给我们,这就是多线程模式处理事务的函数,本文比较一下 PHP 中使用单线程和多线程抓取页面的速度的比较。

我们要抓取 http://www.mafutian.net 网页中的内容,要连续抓 100 次,比较两种方式的执行时间,下面是完整的源代码,可直接复制到 PHP 文件中执行即可:

  1. //	要抓取的网页
  2. $szUrl = 'http://www.mafutian.net';
  3. $count = 100;	//	抓取次数
  4. echo '单线程和多线程抓取网页 '.$szUrl.' '.$count.'次的时间分别是:<br />';
  5. //	=========== 采用单线程方法抓取页面的时间 BEGIN =========== //
  6. $begin_time = getMicrotime();
  7. for($i = 1; $i <= $count; $i++)
  8. {
  9. 	signle_get_url($szUrl);
  10. }
  11. $end_time = getMicrotime();
  12. echo '单线程:'.($end_time - $begin_time).'秒';
  13. echo '<br />';
  14. //	=========== 采用单线程方法抓取页面的时间 END =========== //
  15. //	=========== 采用多线程方法抓取页面的时间 BEGIN =========== //
  16. $urls = array();
  17. for($i = 1;$i <= $count;$i++)
  18. {
  19. 	array_push($urls,$szUrl);
  20. }
  21. $begin_time = getMicrotime();
  22. multi_get_url($urls);
  23. $end_time = getMicrotime();
  24. echo '多线程:'.($end_time - $begin_time).'秒';
  25. echo '<br />';
  26. //	=========== 采用多线程方法抓取页面的时间 END =========== //
  27. //	获取当前的时间戳(含微秒)
  28. function getMicrotime()
  29. {
  30. 	list($usec,$sec) = explode(" ",microtime());
  31. 	return ((float)$sec + (float)$usec);
  32. }
  33. //	curl_init() 单线程抓取页面:signle_get_url()
  34. function signle_get_url($url)
  35. {
  36. 	$curl = curl_init();
  37. 	curl_setopt($curl, CURLOPT_URL, $url);
  38. 	curl_setopt($curl, CURLOPT_HEADER, 0);
  39. 	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  40. 	curl_setopt($curl, CURLOPT_ENCODING, '');
  41. 	$data = curl_exec($curl); 
  42. 	return $data;
  43. }
  44. //	curl_multi_init() 多线程抓取:multi_get_url()
  45. function multi_get_url($url_array, $wait_usec = 0)
  46. {
  47.     if (!is_array($url_array))
  48.     {	    	
  49.         return false;
  50.     }
  51.     $wait_usec = intval($wait_usec);
  52.     $data    = array();
  53.     $handle  = array();
  54.     $running = 0;
  55.     $mh = curl_multi_init(); // 返回一个新 cURL 批处理句柄
  56.     $i = 0;
  57.     foreach($url_array as $url) 
  58.     {
  59.         $ch = curl_init();
  60.         curl_setopt($ch, CURLOPT_URL, $url);
  61.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
  62.         curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  63.         curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  64.         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
  65.         curl_setopt($ch, CURLOPT_MAXREDIRS, 7);
  66.         curl_multi_add_handle($mh, $ch); // 向 curl 批处理会话中添加单独的 curl 句柄
  67.         $handle[$i++] = $ch;
  68.     }
  69.     do{
  70.     	//	运行当前 cURL 句柄的子连接
  71.         curl_multi_exec($mh, $running);	
  72.         if($wait_usec > 0)
  73.         {
  74.             usleep($wait_usec);
  75.         }
  76.     }while($running > 0);
  77.     foreach($handle as $i => $ch) 
  78.     {
  79.     	//	如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流
  80.         $content  = curl_multi_getcontent($ch);
  81.         $data[$i] = (curl_errno($ch) == 0) ? $content : false;
  82.     }
  83.     /* 移除 handle*/
  84.     foreach($handle as $ch) 
  85.     {
  86.     	//	移除 curl 批处理句柄资源中的某个句柄资源
  87.         curl_multi_remove_handle($mh, $ch);
  88.     }
  89.     //	关闭 cURL 句柄
  90.     curl_multi_close($mh);	
  91.     return $data;
  92. }

执行结果如图:

请输入图片名称

单线程和多线程抓取网页 http://www.mafutian.net 100次的时间分别是:

单线程:21.258215904236秒

多线程:3.6812100410461秒

由此可见,多线程所花费的时间远比单线程耗时短。

版权归 马富天个人博客 所有

本文标题:《PHP 中 curl_init() 单线程和 curl_multi_init() 多线程抓取页面的速度比较》

本文链接地址:http://www.mafutian.com/217.html

转载请务必注明出处,小生将不胜感激,谢谢! 喜欢本文或觉得本文对您有帮助,请分享给您的朋友 ^_^

0

0

上一篇《 PHP 模拟登录 》 下一篇《 in_array()检查数组中是否存在某个值,第三个参数 strict 效率比较 》

暂无评论

评论审核未开启
表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情 表情
验证码

TOP10

  • 浏览最多
  • 评论最多