curl实现站外采集的方法和技巧


Posted in PHP onJanuary 31, 2014

选择curl的理由

关于curl与file_get_contents,摘抄一段通俗易懂的对比:
file_get_contents其实是一堆内置的文件操作函数的合并版本,比如file_exists,fopen,fread,fclose,专门提供给懒人用的,而且它主要是用来对付本地文件的,但又是因为懒人的原因,同时加入了对网络文件的支持;
curl是专门用来进行网络交互的库,提供了一堆自定义选项,用来应对不同的环境,稳定性自然要大于file_get_contents。

使用方法

1、开启curl支持

由于php环境安装后默认是没有打开curl支持的,需修改php.ini文件,找到;extension=php_curl.dll,把前面的冒号去掉,重启服务即可;

2、使用curl进行数据抓取

// 初始化一个 cURL 对象 
$curl = curl_init(); 
// 设置你需要抓取的URL 
curl_setopt($curl, CURLOPT_URL, 'http://www.cmx8.cn'); 
// 设置header 
curl_setopt($curl, CURLOPT_HEADER, 1); 
// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
// 运行cURL,请求网页 
$data = curl_exec($curl); 
// 关闭URL请求 
curl_close($curl);

3、通过正则匹配找到关键数据

//$data是curl_exec返回的的值,即采集的目标内容 
preg_match_all("/<li class=\"item\">(.*?)<\/li>/",$data, $out, PREG_SET_ORDER); 
foreach($out as $key => $value){ 
    //此处$value是数组,同时记录找到带匹配字符的整句和单独匹配的字符 
    echo '匹配到的整句:'.$value[0].'
'; 
    echo '单独匹配到的:'.$value[1].'
'; 
}

技巧

1、超时的相关设置

通过curl_setopt($ch, opt) 可以设置一些超时的设置,主要包括:

CURLOPT_TIMEOUT 设置cURL允许执行的最长秒数。
CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。 (在cURL 7.16.2中被加入。从PHP 5.2.3起可使用。 )
CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。
CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。 在cURL 7.16.2中被加入。从PHP 5.2.3开始可用。
CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒。

curl_setopt($ch, CURLOPT_TIMEOUT, 60);   //只需要设置一个秒的数量就可以 
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);    //注意,毫秒超时一定要设置这个 
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);  //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用

2、通过post提交数据,保留cookie

//以下摘抄一个例子过来,用于学习借鉴: 
//Curl 模拟登录 discuz 程序,适合DZ7.0 !extension_loaded('curl') && die('The curl extension is not loaded.');    
$discuz_url = 'http://www.lxvoip.com';//论坛地址    
$login_url = $discuz_url .'/logging.php?action=login';//登录页地址    
$get_url = $discuz_url .'/my.php?item=threads'; //我的帖子    
$post_fields = array();    
//以下两项不需要修改    
$post_fields['loginfield'] = 'username';    
$post_fields['loginsubmit'] = 'true';    
//用户名和密码,必须填写    
$post_fields['username'] = 'lxvoip';    
$post_fields['password'] = '88888888';    
//安全提问    
$post_fields['questionid'] = 0;    
$post_fields['answer'] = '';    
//@todo验证码    
$post_fields['seccodeverify'] = '';    
//获取表单FORMHASH    
$ch = curl_init($login_url);    
curl_setopt($ch, CURLOPT_HEADER, 0);    
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    
$contents = curl_exec($ch);    
curl_close($ch);    
preg_match('/<input\s*type="hidden"\s*name="formhash"\s*value="(.*?)"\s*\/>/i', $contents, $matches);    
if(!empty($matches)) {    
    $formhash = $matches[1];    
} else {    
    die('Not found the forumhash.');    
}    
//POST数据,获取COOKIE    
$cookie_file = dirname(__FILE__) . '/cookie.txt';    
//$cookie_file = tempnam('/tmp');    
$ch = curl_init($login_url);    
curl_setopt($ch, CURLOPT_HEADER, 0);    
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    
curl_setopt($ch, CURLOPT_POST, 1);    
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);    
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);    
curl_exec($ch);    
curl_close($ch);    
//带着上面得到的COOKIE获取需要登录后才能查看的页面内容    
$ch = curl_init($get_url);    
curl_setopt($ch, CURLOPT_HEADER, 0);    
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);    
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);    
$contents = curl_exec($ch);    
curl_close($ch);    
var_dump($contents);
PHP 相关文章推荐
浅谈PHP 闭包特性在实际应用中的问题
Oct 30 PHP
析构函数与php的垃圾回收机制详解
Oct 28 PHP
php实现水仙花数的4个示例分享
Apr 08 PHP
php自定义session示例分享
Apr 22 PHP
PHP与Java对比学习日期时间函数
Jul 03 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
Aug 17 PHP
PHP实现接收二进制流转换成图片的方法
Jan 10 PHP
php pdo操作数据库示例
Mar 10 PHP
php 查找数组元素提高效率的方法详解
May 05 PHP
PHP实现防盗链的方法分析
Jul 25 PHP
php unlink()函数使用教程
Jul 12 PHP
PHP下载文件函数与用法示例
Sep 27 PHP
php使用curl检测网页是否被百度收录的示例分享
Jan 31 #PHP
php使用百度翻译api示例分享
Jan 31 #PHP
php比较两个绝对时间的大小
Jan 31 #PHP
2014过年倒计时示例
Jan 31 #PHP
php curl post 时出现的问题解决
Jan 30 #PHP
分享下页面关键字抓取components.arrow.com站点代码
Jan 30 #PHP
分享下页面关键字抓取www.icbase.com站点代码(带asp.net参数的)
Jan 30 #PHP
You might like
php获得网站访问统计信息类Compete API用法实例
2015/04/02 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
利用PHP生成CSV文件简单示例
2016/12/21 PHP
PHP常用工具函数小结【移除XSS攻击、UTF8与GBK编码转换等】
2019/04/27 PHP
javascript 数组的方法集合
2008/06/05 Javascript
javascript中callee与caller的用法和应用场景
2010/12/08 Javascript
Web Inspector:关于在 Sublime Text 中调试Js的介绍
2013/04/18 Javascript
JS控制图片等比例缩放的示例代码
2013/12/24 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
js检测浏览器版本、核心、是否移动端示例
2014/04/24 Javascript
jquery果冻抖动效果实现方法
2015/01/15 Javascript
调试JavaScript中正则表达式中遇到的问题
2015/01/27 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
有关Promises异步问题详解
2015/11/13 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
2018/02/12 jQuery
vue-quill-editor+plupload富文本编辑器实例详解
2018/10/19 Javascript
Vue商品控件与购物车联动效果的实例代码
2019/07/21 Javascript
基于javascript canvas实现五子棋游戏
2020/07/08 Javascript
python生成器的使用方法
2013/11/21 Python
Python中使用摄像头实现简单的延时摄影技术
2015/03/27 Python
Python 2与Python 3版本和编码的对比
2017/02/14 Python
Python中with及contextlib的用法详解
2017/06/08 Python
python实现统计代码行数的小工具
2019/09/19 Python
python绘制彩虹图
2019/12/16 Python
pandas DataFrame 数据选取,修改,切片的实现
2020/04/24 Python
Flask中sqlalchemy模块的实例用法
2020/08/02 Python
详解HTML5 Canvas绘制时指定颜色与透明度的方法
2016/03/25 HTML / CSS
canvas线条的属性详解
2018/03/27 HTML / CSS
将"引用"作为函数返回值类型的格式、好处和需要遵守的规则
2016/02/09 面试题
介绍下static、final、abstract区别
2015/01/30 面试题
自考生毕业自我鉴定
2013/10/10 职场文书
渡河少年教学反思
2014/02/12 职场文书
银行职员工作失误检讨书
2014/10/14 职场文书
2015年社区消防安全工作总结
2015/10/14 职场文书