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与已存在的Java应用程序集成
Oct 09 PHP
?生?D片??C字串
Dec 06 PHP
30 个很棒的PHP开源CMS内容管理系统小结
Oct 14 PHP
php获取通过http协议post提交过来xml数据及解析xml
Dec 16 PHP
php_screw 1.5:php加密: 安装与使用详解
Jun 20 PHP
jQuery获取json后使用zy_tmpl生成下拉菜单
Mar 27 PHP
CodeIgniter钩子用法实例详解
Jan 20 PHP
Symfony学习十分钟入门经典教程
Feb 03 PHP
2017年最好用的9个php开发工具推荐(超好用)
Oct 23 PHP
Yii2 中实现单点登录的方法
Mar 09 PHP
php中青蛙跳台阶的问题解决方法
Oct 14 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
Mar 23 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
fleaphp下不确定的多条件查询的巧妙解决方法
2008/09/11 PHP
php 获取客户端的真实ip
2009/11/30 PHP
PHP中使用file_get_contents post数据代码例子
2015/02/13 PHP
Ubuntu下安装PHP的mongodb扩展操作命令
2015/07/04 PHP
PHP基于单例模式实现的数据库操作基类
2016/01/15 PHP
Laravel 自动生成验证的实例讲解:login / logout
2019/10/14 PHP
javascript 函数调用规则
2009/08/26 Javascript
jQuery对象[0]是什么含义?
2010/07/31 Javascript
javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图
2013/01/09 Javascript
jQuery中的height innerHeight outerHeight区别示例介绍
2014/06/15 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
jQuery Easyui学习之datagrid 动态添加、移除editor
2016/01/27 Javascript
浅谈vuex 闲置状态重置方案
2018/01/04 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
[02:47]DOTA2亚洲邀请赛 HR战队出场宣传片
2015/02/07 DOTA
python使用cStringIO实现临时内存文件访问的方法
2015/03/26 Python
深入Python函数编程的一些特性
2015/04/13 Python
python 图像平移和旋转的实例
2019/01/10 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
使用django实现一个代码发布系统
2019/07/18 Python
python获取指定日期范围内的每一天,每个月,每季度的方法
2019/08/08 Python
Python编程快速上手——Excel表格创建乘法表案例分析
2020/02/28 Python
耐克奥地利官网:Nike奥地利
2019/08/16 全球购物
技术经理的自我评价范文
2013/12/03 职场文书
公司业务主管岗位职责
2013/12/07 职场文书
车间组长岗位职责
2013/12/20 职场文书
直接有效的自我评价
2014/01/11 职场文书
初中英语教学反思
2014/01/25 职场文书
端午节演讲稿
2014/05/23 职场文书
12.4全国法制宣传日活动方案
2014/11/02 职场文书
世界气象日活动总结
2015/02/27 职场文书
银行催款通知书
2015/04/17 职场文书
标准演讲稿格式结尾应该怎么书写?
2019/07/17 职场文书
Pyhton模块和包相关知识总结
2021/05/12 Python
Java基础——Map集合
2022/04/01 Java/Android