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下使用CURL方式POST数据至API接口的代码
Feb 14 PHP
PHP操作Memcache实例介绍
Jun 14 PHP
php抽奖小程序的实现代码
Jun 18 PHP
解析zend studio中直接导入svn中的项目的方法步骤
Jun 21 PHP
封装ThinkPHP的一个文件上传方法实例
Oct 31 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
Nov 29 PHP
PHP的Yii框架入门使用教程
Feb 15 PHP
PHP面向对象学习之parent::关键字
Jan 18 PHP
Yii框架批量插入数据扩展类的简单实现方法
May 23 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
Jun 13 PHP
thinkPHP5框架导出Excel文件简单操作示例
Aug 03 PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 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
php下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
2012/04/19 PHP
php操作csv文件代码实例汇总
2014/09/22 PHP
php连接mysql数据库最简单的实现方法
2019/09/24 PHP
JavaScript移除数组元素减少长度的方法
2013/09/05 Javascript
JavaScript中的闭包
2016/02/24 Javascript
JS实现鼠标滑过显示边框的菜单效果
2016/09/21 Javascript
js实现图片放大展示效果
2017/08/30 Javascript
Javascript将图片的绝对路径转换为base64编码的方法
2018/01/11 Javascript
JavaScript实现淘宝京东6位数字支付密码效果
2018/08/18 Javascript
微信小程序中插入激励视频广告并获取收益(实例代码)
2019/12/06 Javascript
[02:24]DOTA2亚洲邀请赛 NAVI战队出场宣传片
2015/02/07 DOTA
[46:20]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第二场 1月22日
2021/03/11 DOTA
python比较两个列表大小的方法
2015/07/11 Python
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
2016/07/11 Python
Python实现定时任务
2017/02/08 Python
Python中input与raw_input 之间的比较
2017/08/20 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
2018/03/31 Python
浅谈python之新式类
2018/08/12 Python
seek引发的python文件读写的问题及解决
2019/07/26 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
Python加速程序运行的方法
2020/07/29 Python
python学习笔记之多进程
2020/08/06 Python
体育教育毕业生自荐信
2013/11/21 职场文书
大学生涯自我鉴定
2014/01/16 职场文书
体操比赛口号
2014/06/10 职场文书
奶茶店创业计划书
2014/08/14 职场文书
拆迁委托协议书
2014/09/15 职场文书
教师查摆问题自查报告
2014/10/11 职场文书
2014财务年度工作总结
2014/11/11 职场文书
服装店员工管理制度
2015/08/07 职场文书
MySQL表的增删改查基础教程
2021/04/07 MySQL
详解Python类和对象内容
2021/06/22 Python
彻底弄懂Python中的回调函数(callback)
2022/06/25 Python