php结合curl实现多线程抓取


Posted in PHP onJuly 09, 2015

php结合curl实现多线程抓取

<?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, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
    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('diff_time'=>$diff_time,
   'return'=>$res,
   'header'=>$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,'10');//调用
 var_dump($data);//输出
//如果POST的数据大于1024字节,curl并不会直接就发起POST请求
//发送请求时,header中包含一个空的Expect。curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:"));
?>

我们再来看几个例子

(1)下面这段代码是实现抓取多个URL,然后将抓取的URL的页面代码写入指定的文件

$urls = array(
'https://3water.com/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$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_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(
'https://3water.com/',
'http://www.google.com/',
'http://www.example.com/'
);
$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); // 不将爬取代码写到浏览器,而是转化为字符串
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 Functions 实现并发多线程下载文件

$urls=array(
 'https://3water.com/5w.zip',
 'https://3water.com/5w.zip',
 'https://3water.com/5w.zip'
);
$save_to='./home/';
$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(
 'https://3water.com/5w.zip',
 'https://3water.com/5w.zip',
 'https://3water.com/5w.zip'
);
$save_to='./home/';
$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制作图型计数器的例子
Oct 09 PHP
Phpbean路由转发的php代码
Jan 10 PHP
PHP新手NOTICE错误常见解决方法
Dec 07 PHP
PHP判断远程图片或文件是否存在的实现代码
Feb 20 PHP
浅谈php和.net的区别
Sep 28 PHP
php实现获取文章内容第一张图片的方法
Nov 04 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
php对文件进行hash运算的方法
Apr 03 PHP
php获取错误信息的方法
Jul 17 PHP
实现php删除链表中重复的结点
Sep 27 PHP
TP5框架实现自定义分页样式的方法示例
Apr 05 PHP
php基本函数汇总
Jul 09 #PHP
php+curl 发送图片处理代码分享
Jul 09 #PHP
在Debian系统下配置LNMP的教程
Jul 09 #PHP
PHP+Mysql基于事务处理实现转账功能的方法
Jul 08 #PHP
php将html转成wml的WAP标记语言实例
Jul 08 #PHP
php实现数组中索引关联数据转换成json对象的方法
Jul 08 #PHP
PHP使用pear自带的mail类库发邮件的方法
Jul 08 #PHP
You might like
用PHP生成静态HTML速度快类库
2007/03/18 PHP
phpMyadmin 用户权限中英对照
2010/04/02 PHP
php iconv() : Detected an illegal character in input string
2010/12/05 PHP
php的hash算法介绍
2014/02/13 PHP
PHP 7.0.2 正式版发布
2016/01/08 PHP
PHP简单实现DES加密解密的方法
2016/07/12 PHP
JavaScript 指导方针
2007/04/05 Javascript
javascript对select标签的控制(option选项/select)
2013/01/31 Javascript
手机平板等移动端适配跳转URL的js代码
2014/01/25 Javascript
js如何调用qq互联api实现第三方登录
2014/03/28 Javascript
javascript写的异步加载js文件函数(支持数组传参)
2014/06/07 Javascript
javascript实现复选框超过限制即弹出警告框的方法
2015/02/25 Javascript
jQuery实现的淡入淡出二级菜单效果代码
2015/09/15 Javascript
js判断iframe中元素是否存在的实现代码
2016/12/24 Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
2018/07/10 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
Vue封装全局过滤器Filters的步骤
2020/09/16 Javascript
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
[03:10]超级美酒第四天 fy拉比克秀 大合集
2018/06/05 DOTA
python网络编程学习笔记(二):socket建立网络客户端
2014/06/09 Python
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
在Python的Django框架中调用方法和处理无效变量
2015/07/15 Python
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
pandas DataFrame 行列索引及值的获取的方法
2019/07/02 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
python 监测内存和cpu的使用率实例
2019/11/28 Python
Python如何转换字符串大小写
2020/06/04 Python
django restframework serializer 增加自定义字段操作
2020/07/15 Python
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
关于canvas.toDataURL 在iOS运行失败的问题解决
2020/09/16 HTML / CSS
世界领先的26岁以下学生和青少年旅行预订网站:StudentUniverse
2018/07/01 全球购物
电子专业毕业生自我鉴定
2014/01/22 职场文书
五好家庭申报材料
2014/12/20 职场文书
清明节寄语2015
2015/03/23 职场文书
CSS中Single Div 绘图技巧的实现
2021/06/18 HTML / CSS
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android