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+MySQL的聊天室设计
Oct 09 PHP
php中处理模拟rewrite 效果
Dec 09 PHP
PHP 简单日历实现代码
Oct 28 PHP
通用PHP动态生成静态HTML网页的代码
Mar 04 PHP
php中使用session_set_save_handler()函数把session保存到MySQL数据库实例
Nov 06 PHP
php中explode函数用法分析
Nov 15 PHP
php自定义函数实现二维数组排序功能
Jul 20 PHP
PHP MYSQL简易交互式站点开发
Dec 27 PHP
PHP实现基于面向对象的mysqli扩展库增删改查操作工具类
Jul 18 PHP
Linux下 php7安装redis的方法
Nov 01 PHP
Laravel框架实现的rbac权限管理操作示例
Jan 16 PHP
PHP7新功能总结
Apr 14 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 配置文件中open_basedir选项作用
2009/07/19 PHP
解析php中两种缩放图片的函数,为图片添加水印
2013/06/14 PHP
深入理解PHP中的Session和Cookie
2013/06/21 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
PDO实现学生管理系统
2020/03/21 PHP
img的onload的另类用法
2008/01/10 Javascript
Javascript获取窗口(容器)的大小及位置参数列举及简要说明
2012/12/09 Javascript
网页中返回顶部代码(多种方法)另附注释说明
2013/04/24 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
jQuery实现点击按钮弹出可关闭层的浮动层插件
2015/09/19 Javascript
node.js下LDAP查询实例分享
2015/09/30 Javascript
浅析jQuery Mobile的初始化事件
2015/12/03 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
2016/04/29 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
2016/05/25 Javascript
基于JavaScript实现前端文件的断点续传
2016/10/17 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
2017/03/14 Javascript
js实现简单的日历显示效果函数示例
2019/11/25 Javascript
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
实例讲解JavaScript 计时事件
2020/07/04 Javascript
在Django中创建第一个静态视图
2015/07/15 Python
浅谈python中截取字符函数strip,lstrip,rstrip
2015/07/17 Python
Python的collections模块中namedtuple结构使用示例
2016/07/07 Python
Python subprocess模块常见用法分析
2018/06/12 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
Python操作redis实例小结【String、Hash、List、Set等】
2019/05/16 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
2019/05/29 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
python类中super() 的使用解析
2019/12/19 Python
教师实习的自我鉴定
2013/10/26 职场文书
2014三八妇女节活动总结范文四篇
2014/03/09 职场文书
学校安全责任书
2014/04/14 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
一年级语文上册复习计划
2015/01/17 职场文书
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript