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处理json时中文问题的解决方法
Apr 12 PHP
PHP 时间日期操作实战
Aug 26 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Jul 01 PHP
PHP连接access数据库
Mar 27 PHP
php按单词截取字符串的方法
Apr 07 PHP
PHP实现获取并生成数据库字典的方法
May 04 PHP
PHP十六进制颜色随机生成器功能示例
Jul 24 PHP
ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
Jul 30 PHP
thinkPHP5框架闭包函数与子查询传参用法示例
Aug 02 PHP
PHP后期静态绑定实例浅析
Dec 21 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 27 PHP
PHP如何解决微信文章图片防盗链
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/10/09 PHP
php中批量删除Mysql中相同前缀的数据表的代码
2011/07/01 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
2014/07/25 PHP
Dwz与thinkphp整合下的数据导出到Excel实例
2014/12/04 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
使用ajaxfileupload.js实现ajax上传文件php版
2014/06/26 Javascript
jquery判断复选框是否被选中的方法
2015/10/16 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
2017/05/05 jQuery
Vue 3.0双向绑定原理的实现方法
2019/10/23 Javascript
微信小程序自定义导航栏(模板化)
2019/11/15 Javascript
微信小程序实现简单文字跑马灯
2020/05/26 Javascript
Python中subprocess的简单使用示例
2015/07/28 Python
简单谈谈Python中的反转字符串问题
2016/10/24 Python
Python 实现链表实例代码
2017/04/07 Python
Python搭建FTP服务器的方法示例
2018/01/19 Python
Python3标准库总结
2019/02/19 Python
python制作简单五子棋游戏
2019/06/18 Python
python使用多线程编写tcp客户端程序
2019/09/02 Python
python os模块常用的29种方法使用详解
2020/06/02 Python
python中setuptools的作用是什么
2020/06/19 Python
python利用递归方法实现求集合的幂集
2020/09/07 Python
Python中qutip用法示例详解
2020/10/02 Python
使用django自带的user做外键的方法
2020/11/30 Python
澳大利亚领先的运动鞋商店:Hype DC
2018/03/31 全球购物
请说出几个常用的异常类
2013/01/08 面试题
学期自我评价
2014/01/27 职场文书
擅自离岗检讨书
2014/02/11 职场文书
网络编辑岗位职责
2014/03/18 职场文书
市场部经理岗位职责
2015/02/02 职场文书
检讨书模板大全
2015/05/07 职场文书
2015年艾滋病防治工作总结
2015/05/22 职场文书
关于践行三严三实的心得体会
2016/01/05 职场文书
python用tkinter开发的扫雷游戏
2021/06/01 Python
Java Spring Boot 正确读取配置文件中的属性的值
2022/04/20 Java/Android