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+APACHE实现用户论证的方法
Oct 09 PHP
用phpmyadmin更改mysql5.0登录密码
Mar 25 PHP
使用eAccelerator加密PHP程序
Oct 03 PHP
PHP下对字符串的递增运算代码
Aug 21 PHP
gd库图片下载类实现下载网页所有图片的php代码
Aug 20 PHP
PHP图片处理之图片旋转和图片翻转实例
Nov 19 PHP
php使用curl简单抓取远程url的方法
Mar 13 PHP
PHP中常用的数组操作方法笔记整理
May 16 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
Sep 22 PHP
深入浅析PHP的session反序列化漏洞问题
Jun 15 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
Laravel框架Eloquent ORM修改数据操作示例
Dec 03 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
PHP4.04简明安装
2006/10/09 PHP
thinkphp验证码显示不出来的解决方法
2014/03/29 PHP
Laravel中使用阿里云OSS Composer包分享
2015/02/10 PHP
php 使用array函数实现分页
2015/02/13 PHP
JavaScript Perfection kill 测试及答案
2010/03/23 Javascript
jquery 跳到顶部和底部动画2句代码简单实现
2013/07/18 Javascript
js判断iframe内的网页是否滚动到底部触发事件
2014/03/18 Javascript
jQuery实现边框动态效果的实例代码
2016/09/23 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
2017/03/03 Javascript
Angularjs按需查询实例代码
2017/10/30 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
解决vue 打包发布去#和页面空白的问题
2018/09/04 Javascript
vue 本地服务不能被外部IP访问的完美解决方法
2018/10/29 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
[01:32]2016国际邀请赛中国区预选赛IG战队首日赛后采访
2016/06/27 DOTA
Python Flask基础教程示例代码
2018/02/07 Python
Numpy中转置transpose、T和swapaxes的实例讲解
2018/04/17 Python
利用Python如何实现数据驱动的接口自动化测试
2018/05/11 Python
python中for用来遍历range函数的方法
2018/06/08 Python
基于python实现名片管理系统
2018/11/30 Python
Python lambda表达式用法实例分析
2018/12/25 Python
Python scipy的二维图像卷积运算与图像模糊处理操作示例
2019/09/06 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
python实点云分割k-means(sklearn)详解
2020/05/28 Python
python从Oracle读取数据生成图表
2020/10/14 Python
python模拟点击在ios中实现的实例讲解
2020/11/26 Python
在网上学习全世界最好的课程:Coursera
2017/11/07 全球购物
Antler英国官网:购买安特丽行李箱、拉杆箱
2019/08/25 全球购物
含精油的天然有机化妆品:Indemne
2019/08/27 全球购物
毕业生就业自荐信
2013/12/04 职场文书
英语课外活动总结
2014/08/27 职场文书
政风行风整改报告
2014/11/06 职场文书
党员个人自我评价
2015/03/03 职场文书
再见,2019我们不负使命;你好,2020我们砥砺前行
2020/01/03 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript