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中用文本文件做数据库的实现方法
Mar 27 PHP
PHP 数据库树的遍历方法
Feb 06 PHP
PHP中copy on write写时复制机制介绍
May 13 PHP
PHP中preg_match正则匹配中的/u、/i、/s含义
Apr 17 PHP
作为程序员必知的16个最佳PHP库
Dec 09 PHP
php实现无限级分类查询(递归、非递归)
Mar 10 PHP
Zend Framework实现多文件上传功能实例
Mar 21 PHP
PHP对象链式操作实现原理分析
Oct 09 PHP
php实现的简单数据库操作Model类
Nov 16 PHP
phpcms配置列表页以及获得文章发布时间
Jul 04 PHP
PHP开发之用微信远程遥控服务器
Jan 25 PHP
PHP后期静态绑定实例浅析
Dec 21 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实现单链表的实例代码
2013/03/22 PHP
ThinkPHP权限认证Auth实例详解
2014/07/22 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
PHP实现文件上传后台处理脚本
2020/03/04 PHP
学习jquery之一
2007/04/27 Javascript
js 数组的for循环到底应该怎么写?
2010/05/31 Javascript
使用jquery与图片美化checkbox和radio控件的代码(打包下载)
2010/11/11 Javascript
JS面向对象编程浅析
2011/08/28 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
JavaScript中window.open用法实例详解
2015/04/15 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
JavaScript编写带旋转+线条干扰的验证码脚本实例
2016/05/30 Javascript
JavaScript中运算符规则和隐式类型转换示例详解
2017/09/06 Javascript
JavaScript 隐性类型转换步骤浅析
2018/03/15 Javascript
微信小程序实现保存图片到相册功能
2018/11/30 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
2019/01/08 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
python爬取网站数据保存使用的方法
2013/11/20 Python
Windows下Anaconda2安装NLTK教程
2018/09/19 Python
Python调用服务接口的实例
2019/01/03 Python
Python绘制并保存指定大小图像的方法
2019/01/10 Python
对python中字典keys,values,items的使用详解
2019/02/03 Python
Python3 实现串口两进程同时读写
2019/06/12 Python
PyQt5 界面显示无响应的实现
2020/03/26 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
结婚典礼证婚词
2014/01/08 职场文书
法律专业自荐信
2014/06/03 职场文书
红色旅游心得体会
2014/09/03 职场文书
群众路线自我剖析材料
2014/10/08 职场文书
三峡人家导游词
2015/01/31 职场文书
幼儿园大班教师个人工作总结
2015/02/05 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书
2019年教师入党申请书
2019/06/27 职场文书
研究生毕业登记表的自我鉴定范文
2019/07/15 职场文书