PHP CURL或file_get_contents获取网页标题的代码及两者效率的稳定性问题


Posted in PHP onNovember 30, 2015

PHP CURL与file_get_contents函数都可以获取远程服务器上的文件保存到本地,但在性能上面两者完全不在同一个级别,下面我先来介绍PHP CURL或file_get_contents函数应用例子,然后再简单的给各位介绍一下它们的一些小区别吧。

推荐方法 CURL获取

<?php
$c = curl_init();
$url = '3water.com';
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($c);
curl_close($c);
$pos = strpos($data,'utf-8');
if($pos===false){$data = iconv("gbk","utf-8",$data);}
preg_match("/<title>(.*)<\/title>/i",$data, $title);
echo $title[1];
?>

使用file_get_contents

<?php
$content=file_get_contents("https://3water.com/");
$pos = strpos($content,'utf-8');
if($pos===false){$content = iconv("gbk","utf-8",$content);}
$postb=strpos($content,'<title>')+7;
$poste=strpos($content,'</title>');
$length=$poste-$postb;
echo substr($content,$postb,$length);
?>

看看file_get_contents性能

1)fopen/file_get_contents 每次请求远程URL中的数据都会重新做DNS查询,并不对DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS 查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen/file_get_contents 好很多。
2)fopen/file_get_contents在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。(设置header头应该可以)
3)fopen/file_get_contents函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
4)curl可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen/file_get_contents只能使用get方式获取数据。
5)fopen/file_get_contents 不能正确下载二进制文件
6)fopen/file_get_contents 不能正确处理ssl请求
7)curl 可以利用多线程
8)使用 file_get_contents 的时候如果 网络出现问题, 很容易堆积一些进程在这里
9)如果是要打一个持续连接,多次请求多个页面。那么file_get_contents就会出问题。取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。对做采集抓取的用curl,如果还有同不相信下面我们再做个测试

curl与file_get_contents性能对比PHP源代码如下:

1829.php

<?php
/**
* 通过淘宝IP接口获取IP地理位置
* @param string $ip
* @return: string
**/
function getCityCurl($ip)
{
 $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
 $ch = curl_init();
 $timeout = 5;
 curl_setopt ($ch, CURLOPT_URL, $url);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
 $file_contents = curl_exec($ch);
 curl_close($ch);
 $ipinfo=json_decode($file_contents);
 if($ipinfo->code=='1'){
  return false;
 }
 $city = $ipinfo->data->region.$ipinfo->data->city;
 return $city;
}
function getCity($ip)
{
 $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
 $ipinfo=json_decode(file_get_contents($url));
 if($ipinfo->code=='1'){
  return false;
 }
 $city = $ipinfo->data->region.$ipinfo->data->city;
 return $city;
}
// for file_get_contents
$startTime=explode(' ',microtime());
$startTime=$startTime[0] + $startTime[1];
for($i=1;$i<=10;$i++)
{
 echo getCity("121.207.247.202")."</br>";
}
$endTime = explode(' ',microtime());
$endTime = $endTime[0] + $endTime[1];
$totalTime = $endTime - $startTime;
echo 'file_get_contents:'.number_format($totalTime, 10, '.', "")." seconds</br>";
//for curl
$startTime2=explode(' ',microtime());
$startTime2=$startTime2[0] + $startTime2[1];
for($i=1;$i<=10;$i++)
{
 echo getCityCurl('121.207.247.202')."</br>";
}
$endTime2 = explode(' ',microtime());
$endTime2=$endTime2[0] + $endTime2[1];
$totalTime2 = $endTime2 - $startTime2;
echo "curl:".number_format($totalTime2, 10, '.', "")." seconds";
?>

测试访问

file_get_contents速度:4.2404510975 seconds
curl速度:2.8205530643 seconds
curl比file_get_contents速度快了30%左右,最重要的是服务器负载更低.

ps:php函数file_get_contents与curl效率及稳定性问题

习惯了使用方便快捷的file_get_contents函数抓取别家网站内容,但是总是会遇到获取失败的问题,尽管按照手册中的例子设置了超时,可多数时候不好使:

$config['context'] = stream_context_create(array('http' => array('method' => "GET",'timeout' => 5))); 
'timeout' => 5//这个超时时间不稳定,经常不好使。这时候,看一下服务器的连接池,会发现一堆类似下面的错误,让你头疼万分:

file_get_contents(http://***): failed to open stream… 

不得已,安装了curl库,写了一个函数替换:

function curl_get_contents($url) 
{ 
 $ch = curl_init(); 
 curl_setopt($ch, CURLOPT_URL, $url);   //设置访问的url地址 
 //curl_setopt($ch,CURLOPT_HEADER,1);   //是否显示头部信息 
 curl_setopt($ch, CURLOPT_TIMEOUT, 5);   //设置超时 
 curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_); //用户访问代理 User-Agent 
 curl_setopt($ch, CURLOPT_REFERER,_REFERER_);  //设置 referer 
 curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);  //跟踪301 
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //返回结果 
 $r = curl_exec($ch); 
 curl_close($ch); 
 return $r; 
}

如此,除了真正的网络问题外,没再出现任何问题。

这是别人做过的关于curl和file_get_contents的测试:

file_get_contents抓取google.com需用秒数:

2.31319094  
2.30374217  
2.21512604  
3.30553889  
2.30124092 

curl使用的时间:

0.68719101  
0.64675593  
0.64326  
0.81983113  
0.63956594 

差距很大吧?呵呵,从我使用的经验来说,这两个工具不只是速度有差异,稳定性也相差很大。建议对网络数据抓取稳定性要求比较高的朋友使用上面的 curl_file_get_contents函数,不但稳定速度快,还能假冒浏览器欺骗目标地址哦!

PHP 相关文章推荐
PHP 将图片按创建时间进行分类存储的实现代码
Jan 05 PHP
比较时间段一与时间段二是否有交集的php函数
May 31 PHP
批量获取memcache值并按key的顺序返回的实现代码
Jun 14 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
Apr 26 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
Aug 22 PHP
php图片水印添加、压缩、剪切的封装类实现
Apr 18 PHP
phplist及phpmailer(组合使用)通过gmail发送邮件的配置方法
Mar 30 PHP
深入理解PHP中的empty和isset函数
May 26 PHP
php获取数据库结果集方法(推荐)
Jun 01 PHP
php smtp实现发送邮件功能
Jun 22 PHP
thinkphp5 migrate数据库迁移工具
Feb 20 PHP
PHP rsa加密解密算法原理解析
Dec 09 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
Nov 30 #PHP
PHP curl模拟登录带验证码的网站
Nov 30 #PHP
PHP可变函数学习小结
Nov 29 #PHP
PHP可变变量学习小结
Nov 29 #PHP
PHP中对数组的一些常用的增、删、插操作函数总结
Nov 27 #PHP
详解PHP对数组的定义以及数组的创建方法
Nov 27 #PHP
实例简介PHP的一些高级面向对象编程的特性
Nov 27 #PHP
You might like
php+mysql实现无限级分类 | 树型显示分类关系
2006/11/19 PHP
解决GD中文乱码问题
2007/02/14 PHP
PHP中的extract的作用分析
2008/04/09 PHP
关于PHP5 Session生命周期介绍
2010/03/02 PHP
thinkphp连贯操作实例分析
2014/11/22 PHP
php 利用array_slice函数获取随机数组或前几条数据
2015/09/30 PHP
PHP动态生成指定大小随机图片的方法
2016/03/25 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
laravel 解决groupBy时出现的错误 isn't in Group By问题
2019/10/17 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
js中的值类型和引用类型小结 文字说明与实例
2010/12/12 Javascript
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
2013/12/05 Javascript
Javascript selection的兼容性写法介绍
2013/12/20 Javascript
js 金额格式化来回转换示例
2014/02/23 Javascript
JS中判断JSON数据是否存在某字段的方法
2014/03/07 Javascript
jQuery实现360°全景拖动展示
2015/03/18 Javascript
JS表单数据验证的正则表达式(常用)
2017/02/18 Javascript
vue.js使用v-pre与v-html输出HTML操作示例
2018/07/07 Javascript
vue 中滚动条始终定位在底部的方法
2018/09/03 Javascript
React实现全选功能
2020/08/25 Javascript
JQuery使用数组遍历跳出each循环
2020/09/01 jQuery
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
Python中的hypot()方法使用简介
2015/05/18 Python
python实现在windows服务中新建进程的方法
2015/06/30 Python
Python 基础知识之字符串处理
2017/01/06 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
10分钟用python搭建一个超好用的CMDB系统
2019/07/17 Python
Python生命游戏实现原理及过程解析(附源代码)
2019/08/01 Python
Python带参数的装饰器运行原理解析
2020/06/09 Python
css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况
2016/12/06 HTML / CSS
Html5无刷新修改browser Url的方法
2014/01/15 HTML / CSS
维稳工作承诺书
2015/01/20 职场文书
服装店员工管理制度
2015/08/07 职场文书
《小乌鸦爱妈妈》教学反思
2016/02/19 职场文书