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制作图型计数器的例子
Oct 09 PHP
Zend 输出产生XML解析错误
Mar 03 PHP
PHP初学者常见问题集合 修正版(21问答)
Mar 23 PHP
PHP 函数执行效率的小比较
Oct 17 PHP
PHP读取XML值的代码(推荐)
Jan 01 PHP
fleaphp rolesNameField bug解决方法
Apr 23 PHP
常用的PHP数据库操作方法(MYSQL版)
Jun 08 PHP
解析百度搜索结果link?url=参数分析 (全)
Oct 09 PHP
php获取网页中图片、DIV内容的简单方法
Jun 19 PHP
PHP常用的排序和查找算法
Aug 06 PHP
24条货真价实的PHP代码优化技巧
Jul 28 PHP
php基于环形链表解决约瑟夫环问题示例
Nov 07 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小技巧之过滤ascii控制字符
2014/05/14 PHP
PHP 输出缓冲控制(Output Control)详解
2016/08/25 PHP
PHP判断是否微信访问的方法示例
2019/03/27 PHP
从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
2019/04/03 PHP
JavaScript通过RegExp实现客户端验证处理程序
2013/05/07 Javascript
javascript获取URL参数与参数值的示例代码
2013/12/20 Javascript
用js格式化金额可设置保留的小数位数
2014/05/09 Javascript
基于JS实现PHP的sprintf函数实例
2015/11/14 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
静态页面html中跳转传值的JS处理技巧
2016/06/22 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
AngularJS中的路由使用及实现代码
2017/10/09 Javascript
使用Vue自定义数字键盘组件(体验度极好)
2017/12/19 Javascript
npm全局模块卸载及默认安装目录修改方法
2018/05/15 Javascript
深入解析koa之异步回调处理
2019/06/17 Javascript
简单谈谈javascript高级特性
2019/09/04 Javascript
vue跳转同一个组件,参数不同,页面接收值只接收一次的解决方法
2019/11/05 Javascript
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
python框架Django实战商城项目之工程搭建过程图文详解
2020/03/09 Python
解决Python 异常TypeError: cannot concatenate 'str' and 'int' objects
2020/04/08 Python
python简单实现最大似然估计&amp;scipy库的使用详解
2020/04/15 Python
python进度条显示-tqmd模块的实现示例
2020/08/23 Python
python 实现批量图片识别并翻译
2020/11/02 Python
高清屏下canvas重置尺寸引发的问题的解决
2019/10/14 HTML / CSS
租租车:国际租车、美国租车、欧洲租车、特价预订国外租车(中文服务)
2018/03/28 全球购物
Molly Bracken法国电子商店:法国女性时尚品牌
2019/07/24 全球购物
庆中秋节主题活动方案
2014/02/03 职场文书
《商鞅南门立木》教学反思
2014/02/16 职场文书
成绩报告单家长评语
2014/12/30 职场文书
关于观后感的作文
2015/06/18 职场文书
小学三年级语文教学反思
2016/03/03 职场文书
Django cookie和session的应用场景及如何使用
2021/04/29 Python
Golang 切片(Slice)实现增删改查
2022/04/22 Golang
Python使用Opencv打开笔记本电脑摄像头报错解问题及解决
2022/06/21 Python
详解MySQL的内连接和外连接
2023/05/08 MySQL