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 相关文章推荐
一个ftp类(ini.php)
Oct 09 PHP
php中将html中的br换行符转换为文本输入中的换行符
Mar 26 PHP
基于PHP导出Excel的小经验 完美解决乱码问题
Jun 10 PHP
PHPAnalysis中文分词类详解
Jun 13 PHP
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
Jun 23 PHP
PHP实现更新中间关联表数据的两种方法
Sep 01 PHP
thinkphp3.2中Lite文件替换框架入口文件或应用入口文件的方法
May 21 PHP
ThinkPHP进程计数类Process用法实例详解
Sep 25 PHP
配置Nginx+PHP的正确思路与过程
May 10 PHP
Yii2中SqlDataProvider用法示例
Sep 22 PHP
php闭包中使用use声明变量的作用域实例分析
Aug 09 PHP
CI框架实现创建自定义类库的方法
Dec 25 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
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
php+ajax+json 详解及实例代码
2016/12/12 PHP
基于ThinkPHP删除目录及目录文件函数
2020/10/28 PHP
来自国外的页面JavaScript文件优化
2010/12/08 Javascript
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
javascript full screen 全屏显示页面元素的方法
2013/09/27 Javascript
jQuery中ready事件用法实例
2015/01/19 Javascript
JavaScript中数据结构与算法(一):栈
2015/06/19 Javascript
jquery实现的V字形显示效果代码
2015/10/27 Javascript
vue.js  父向子组件传参的实例代码
2017/10/29 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
QRCode.js二维码生成并能长按识别
2018/10/16 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
2020/11/17 Vue.js
[05:05]第三天的dota2
2013/07/29 DOTA
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
[02:59]2014DOTA2西雅图国际邀请赛 圆满落幕中国夺冠
2014/07/23 DOTA
Python中还原JavaScript的escape函数编码后字符串的方法
2014/08/22 Python
初步讲解Python中的元组概念
2015/05/21 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
简单了解python装饰器原理及使用方法
2019/12/18 Python
Python hashlib常见摘要算法详解
2020/01/13 Python
python构造函数init实例方法解析
2020/01/19 Python
PyCharm 无法 import pandas 程序卡住的解决方式
2020/03/09 Python
python cookie反爬处理的实现
2020/11/01 Python
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
电子商务网站的创业计划书
2014/01/05 职场文书
老人祝寿主持词
2014/03/28 职场文书
求职信怎么写范文
2014/05/26 职场文书
高中班级口号
2014/06/09 职场文书
新闻学专业求职信
2014/07/28 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
PHP对接阿里云虚拟号的实现(号码隐私保护)
2021/04/06 PHP