CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。

使用CURL的PHP扩展完成一个HTTP请求的发送一般有以下几个步骤:

  1. 初始化连接句柄;
  2. 设置CURL选项;
  3. 执行并获取结果;
  4. 释放CURL连接句柄。

一、使用curl模拟GET请求

$curl=curl_init();  //初始化curl句柄
$url="http://www.conglinfeng.com/together/detail.php?show_ID=5";  //要请求的url地址
curl_setopt($curl, CURLOPT_URL,$url);  //设置curl的参数,即要请求的url是$url
curl_exec($curl);  //执行操作
curl_close($curl);  //关闭句柄

执行curl_exec()时,成功时会输出网页代码,并且返回值为 TRUE,在失败时返回 FALSE。 然而,如果 CURLOPT_RETURNTRANSFER选
项被设置,函数执行成功时会返回执行的结果,失败时返回 FALSE 。

二、使用curl模拟post请求

$curl=curl_init();
$url="./register.php";
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, true);  //设置请求为post
$post_data=array('username'=>"嘿嘿",'password'=>'111111','confirm'=>'111111','email'=>"986992484@qq.com");   //要发送的数据组装成一个数组
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  //post的数据内容
curl_exec($curl);
curl_close($curl);

register.php:

var_dump($_POST);

三、处理响应的数据

curl_exec()执行时会直接把响应数据输出,如果不需要直接输出,可以加:curl_setopt($curl, CURLOPT_RETURNTRANSFER, true) ;

$url="./register.php";
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, true);  //设置请求为post
$post_data=array('username'=>"嘿嘿",'password'=>'111111','confirm'=>'111111','email'=>"986992484@qq.com");
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  //post的数据内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true) ; //请求执行时,不将响应数据直接输出,而是以返回值的形式输出响应数据
$res=curl_exec($curl);
echo $res;  //少了这句就输不出来了
curl_close($curl);

四、模拟post 文件上传

$url="./register.php";
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, true);  //设置请求为post
$post_data=array('logo'=>'@D:\wamp\wamp\www\czbk\php&mysql\1.png'); // logo是$_FILES的name,后面的是图片路径,加@表示这是一个文件而不是字符串
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  //post的数据内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true) ; //请求执行时,不将响应数据直接输出,而是以返回值的形式输出响应数据
$res=curl_exec($curl);
echo $res;
curl_close($curl);

五、输出响应头

curl默认是不输出响应头的,如果要输出,则要加:curl_setopt($curl, CURLOPT_HEADER, true);

$url="http://www.conglinfeng.com/together/member/index.php";
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_HEADER, true);  //将响应头输出,默认是不输出的
//  HTTP/1.1 200 OK Date: Thu, 15 Sep 2016 14:49:28 GMT Server: Apache/2.4.4 (Win32) PHP/5.4.16 X-Powered-By: PHP/5.4.16 Content-Length: 692 Content-Type: text/html
curl_exec($curl);
curl_close($curl);

六、实例:CURL模拟登陆

可以简单和有效地抓取网页并采集内容,设置cookie完成模拟登录网页,curl提供了丰富的函数,开发者可以从PHP手册中获取更多关于cURL信息。本文以模拟登录开源中国(oschina)为例,和大家分享cURL的使用。

PHP的curl()在抓取网页的效率方面是比较高的,而且支持多线程,而file_get_contents()效率就要稍低些,当然,使用curl时需要开启下curl扩展。

先来看登录部分的代码:

//模拟登录
function login_post($url, $cookie, $post) { $curl = curl_init();//初始化curl模块 curl_setopt($curl, CURLOPT_URL, $url);//登录提交的地址 curl_setopt($curl, CURLOPT_HEADER, 0);//是否显示头信息 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);//是否自动显示返回的信息 curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); //设置Cookie信息保存在指定的文件中 curl_setopt($curl, CURLOPT_POST, 1);//post方式提交 curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));//要提交的信息 curl_exec($curl);//执行cURL curl_close($curl);//关闭cURL资源,并且释放系统资源
} 

函数login_post()首先初始化curl_init(),然后使用curl_setopt()设置相关选项信息,包括要提交的url地址,保存的cookie文件,post的数据(用户名和密码等信息),是否返回信息等等,然后curl_exec执行curl,最后curl_close()释放资源。注意PHP自带的http_build_query()可以将数组转换成相连接的字符串。

接下来如果登录成功后,我们要获取登录成功后的页面信息。

//登录成功后获取数据
function get_content($url, $cookie) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //读取cookie $rs = curl_exec($ch); //执行cURL抓取页面内容 curl_close($ch); return $rs;
} 

函数get_content()中也是先初始化curl,然后设置相关选项,执行curl,释放资源。其中我们设置CURLOPT_RETURNTRANSFER为1即自动返回信息,而CURLOPT_COOKIEFILE可以读取到登录时保存的cookie信息,最后将页面内容返回。

我们的最终目的是要获取到模拟登录后的信息,也就是只有正常登录成功后才能获取的有用信息。接下来我们以登录开源中国的移动版为例,看看如何抓取到登录成功后的信息。

//设置post的数据
$post = array ( 'email' => 'oschina账户', 'pwd' => 'oschina密码', 'goto_page' => '/my', 'error_page' => '/login', 'save_login' => '1', 'submit' => '现在登录'
); //登录地址
$url = "http://m.oschina.net/action/user/login";
//设置cookie保存路径
$cookie = dirname(__FILE__) . '/cookie_oschina.txt';
//登录后要获取信息的地址
$url2 = "http://m.oschina.net/my";
//模拟登录
login_post($url, $cookie, $post);
//获取登录页的信息
$content = get_content($url2, $cookie);
//删除cookie文件
@ unlink($cookie);
//匹配页面信息
$preg = "/<td class='portrait'>(.*)<\/td>/i";
preg_match_all($preg, $content, $arr);
$str = $arr[1][0];
//输出内容
echo $str; 

七、封装CURL

为了便于日后调用,我们可以把这些操作封装起来。

1.模拟get或post请求

/*** curl()   curl模拟请求---一个参数是get请求,两个参数是post请求** 上传文件$post=array('logo'=>'@D:\wamp\wamp\www\czbk\php&mysql\1.png'); * logo是$_FILES的name,后面的是图片路径,加@表示这是一个文件而不是字符串** @param string $url   模拟请求的url* @param array $post   post请求时要提交的数据* @param boolean $header  是否要将响应头输出* @return string $str   返回响应结果*/
function curl($url,$post=array(),$header=false){if(!$url)   return;//设置资源句柄$curl=curl_init();curl_setopt($curl, CURLOPT_URL,$url);//如果传$post,则说明是post请求if($post && is_array($post) && count($post)>0){curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, $post);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //不验证证书curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); //不验证证书}//请求执行时,不将响应数据直接输出,而是以返回值的形式输出响应数据curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //决定要不要将响应头输出curl_setopt($curl, CURLOPT_HEADER,$header); $str=curl_exec($curl); //IGNORE 忽略转换时的错误,如果没有ignore参数,所有该字符后面的字符串都无法被保存。$str = iconv("UTF-8","GBK//IGNORE",$str);curl_close($curl);return $str;
}

2.模拟登陆

/*** curl_login()   curl模拟登陆** @param string $logUrl   登陆地址url* @param string $desUrl   要访问页面的url* @param array $post    要提交的数据* @param string $cookie=''  存储cookie的文件路径* @return string $str   返回响应结果*/
function curl_login($logUrl,$desUrl,$post,$cookie=''){/********模拟登陆**********///初始化curl模块 $curl = curl_init();//登录提交的地址 curl_setopt($curl, CURLOPT_URL,$logUrl);//是否显示头信息curl_setopt($curl, CURLOPT_HEADER, 0); //是否自动显示返回的信息 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);//设置Cookie信息保存在指定的文件中 if(!$cookie)  $cookie=dirname(__FILE__) . '/cookie.txt';if(!file_exists($cookie))}{$fp=fopen($cookie, 'w'); fclose($fp);}curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); //post方式提交 curl_setopt($curl, CURLOPT_POST, 1);//提交信息,http_build_query()可以将数组转换成相连接的字符串。curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); //执行cURL并关闭cURL资源,并且释放系统资源 curl_exec($curl);curl_close($curl);/********登陆后获取数据**********/$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $desUrl); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //读取cookie curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); $rs = curl_exec($ch); //执行cURL抓取页面内容 curl_close($ch); return $rs;
}

也可以把curl的操作封装成一个类 Curl.class.php

<?php/***  CURL操作类,可用于模拟请求*  @author leshen <986992484@qq.com>*  @version 1.1*  usage:* 1.设置选项*  $options=array(*    'isReturn'=>true,   //将响应结果返回。如果不想获取源码而是想渲染页面,请设置为false*   'isHeader'=>true,   //将响应头返回*   );*  $curl=new Curl($options);*  2.模拟一般的get请求*  $curl=new Curl();*  $url="https://www.baidu.com";*  var_dump($curl->curl_get($url));*  3.模拟需要盗链的get请求(查询四六级为例)*  $curl=new Curl();*  $url='http://www.chsi.com.cn/cet/query';*  $referer="http://www.chsi.com.cn/cet";*  $data=array('xm'=>'钟林生','zkzh'=>'360021161218718');*  $respn=$curl->curl_get_chain($url,$data,$referer);*  var_dump($respn);*  4.模拟post请求(查询四六级为例)*     $data=array(*  'name'=>'王勇平',*     'province'=>'江西',*  'school'=>'江西师范大学',*    'type'=>'1'*   );* $url='http://cet.zy62.com/query/2';* $curl=new Curl();* var_dump($curl->curl_post($url,$data));*/class Curl{/*** curl资源句柄* @var resource*/private $curl;/*curl选项*/private $isReturn;   //是否将响应结果返回private $isHeader;   //是否将响应头返回private $timeout;    //超时时间private $userAgent;  //客户端代理private $verifyPeer; //是否终止cURL从服务端进行验证private $verifyHost; //检查服务器SSL证书中是否存在一个公用名/*** 构造方法,用于实例化一个curl对象*/public function __construct($options=array()){/*初始化资源句柄*/$this->curl=curl_init();/*初始化curl选项*/$this->isReturn=isset($options['isReturn'])?$options['isReturn']:ture;$this->isHeader=isset($options['isHeader'])?$options['isHeader']:false;$this->timeout=isset($options['timeout'])?$options['timeout']:30;$this->userAgent=isset($options['userAgent'])?$options['timeout']:isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']: 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';$this->verifyPeer=isset($options['verifyPeer'])?$options['verifyPeer']:false;$this->verifyHost=isset($options['verifyHost'])?$options['verifyHost']:2;}   /*** 设置curl选项* @param  string   $url     请求的url* @param  boolean  $ssl  是否以https协议传输* @return void */  private function setOption($url,$ssl){/*设置curl选项*/curl_setopt($this->curl, CURLOPT_URL, $url);//URLcurl_setopt($this->curl, CURLOPT_USERAGENT, $this->userAgent);//userAgent,请求代理信息curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);//设置超时时间/*SSL相关*/if ($ssl) {curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER,$this->verifyPeer);//禁用后cURL将终止从服务端进行验证curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST,$this->verifyHost);//检查服务器SSL证书中是否存在一个公用名(common name)。}/*响应结果*/curl_setopt($this->curl, CURLOPT_HEADER, $this->isHeader);//是否返回响应头curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, $this->isReturn);//curl_exec()是否返回响应结果}/*** 执行curl请求* @return string  返回响应内容*/   private function exec(){/*发出请求*/$response = curl_exec($this->curl);if (false === $response) {echo '<br>', curl_error($this->curl), '<br>';return false;}curl_close($this->curl);return $response;}/*** curl模拟post请求,返回响应的内容* @param  string   $url        请求的url* @param  array    $data         发送的数据,数组* @param  boolean  $ssl         是否以https协议传输,默认为true* @return string   $response   返回响应的内容*/   public function curl_post($url, $data, $ssl=true) {/*设置选项*/$this->setOption($url,$ssl);/*处理post相关选项*/curl_setopt($this->curl, CURLOPT_POST, true);// 是否为POST请求curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data);// 设置post的内容/*执行curl请求*/if($this->isReturn){return $this->exec();}$this->exec();}/*** curl模拟一般的get请求,返回响应的内容* @param  string   $url       请求的url,可以带查询参数* @param  boolean  $ssl      是否以https协议传输,默认为true* @return string   $response   返回响应的内容*/   public function curl_get($url,$ssl=true) {/*设置选项*/$this->setOption($url,$ssl);/*执行curl请求*/if($this->isReturn){return $this->exec();}$this->exec();}    /*** curl模拟需要盗链的get请求,返回响应的内容* @param  string   $url       请求的url* @param  array    $data         查询参数,数组形式,方法内会自动转换为字符串形式* @param  string   $referer  盗链的url* @param  boolean  $ssl      是否以https协议传输,默认为true* @return string   $response   返回响应的内容*/   public function curl_get_chain($url,$data,$referer,$ssl=true){/*设置选项*/$this->setOption($url,$ssl);$param='';foreach ($data as $k => $v) {$param.= urlencode($k).'='.urlencode($v).'&';}/*设置查询参数*/curl_setopt($this->curl, CURLOPT_POST, 0);curl_setopt($this->curl, CURLOPT_POSTFIELDS, $param);/*设置referer盗链*/curl_setopt($this->curl, CURLOPT_REFERER, $referer);/*执行curl请求*/if($this->isReturn){return $this->exec();}$this->exec();}
}

PHP使用CURL抓取网页相关推荐

  1. php使用curl抓取网页自动跳转问题处理

    问题分析: 请求抓取http://go.com数据: function curlGet($url) {$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $ ...

  2. php curl抓去网页名单,PHP CURL抓取网页 simple_html_dom类

    $ch=curl_init();$timeout = 1;//echo CURLOPT_URL; // CURLOPT_URL: 这是你想用PHP取回的URL地址.你也可以在用curl_init()函 ...

  3. php curl 下载网页,php 通过cURL函数抓取网页、下载网页的简单示例

    这篇文章主要为大家详细介绍了php 通过cURL函数抓取网页.下载网页的简单示例,具有一定的参考价值,可以用来参考一下. php通过cURL函数抓取和下载网页,感兴趣的小伙伴,下面一起跟随512笔记的 ...

  4. php curl_setopt抓取内容,PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)

    通过curl_setopt()函数可以方便快捷的抓取网页(采集很方便),curl_setopt 是php的一个扩展库 使用条件:需要在php.ini 中配置开启.(PHP 4 >= 4.0.2) ...

  5. curl抓取页面时遇到重定向的解决方法(转)

    用php的curl抓取网页遇到了问题,为阐述方便,将代码简化如下: [php] view plaincopy <?php function curlGet($url) { $ch = curl_ ...

  6. php正则获取li,用正则表达式抓取网页中的ul 和 li标签中最终的值!

    获取你要抓取的页面 const string URL = "http://www.hn3ddf.gov.cn/price/GetList.html?pageno=1";       ...

  7. php抓取curl下载文件,PHP 利用 Curl 函数实现多线程抓取网页和下载文件

    PHP 利用 Curl Functions 可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,然而因为php语言本身不支持多线程,所以开发爬虫程序效率并不高,因此经常需要借助Cur ...

  8. 用curl+PHP抓取网页上所需要的数据

    最近使用后台的时候老是发现有些信息没法导出,又不想一个个复制很麻烦,想起以前做的一个小功能,用来抓取网页上的可用数据填充自己的数据库,由于网站需要登录才能访问,所以加上了curl的模拟登录 <? ...

  9. php curl与正则表达式抓取网页数据的例子

    php使用curl和 正则表达式抓取网页数据示例,这里是抓取某网站的小说. 利用 curl和正则表达式做的一个针对磨铁中文网非vip章节的小说抓取器,支持输入小说ID下载小说. 依赖项:curl 可以 ...

最新文章

  1. Kubernetes 架构(下)【转】
  2. 【NIO】缓存区buffer
  3. 修改value_Java 反射修改String引发的思考?
  4. Lesson 016 —— python 元组
  5. 去分库分表的亿级数据NewSQL实践之旅
  6. Winform中设置ZedGraph曲线图的字体样式是避免出现边框
  7. Echarts地图初体验
  8. mysql InnoDB 聚集索引,二级索引
  9. CF-778 C.Peterson Polyglot (Trie合并)
  10. T-sql检测文件夹是否存在
  11. 蓝桥杯第八届省赛JAVA真题----分巧克力
  12. 【程序人生】Web前端工程师岗位分析报告
  13. SPSS实现单样本t检验
  14. 360浏览器是ie浏览器吗?有什么区别
  15. matlab 二值图像连通区域标记法,一种二值图像连通区域标记的简单快速算法_葛春平...
  16. sendto()_Linux C函数
  17. html页面中引入script标签的src的写法,/与//的区别
  18. iOS项目中用到的一些第三方库
  19. rabbit安装教程
  20. 力扣121、122、309、714(C语言版)动态规划股票问题

热门文章

  1. cisco 无线AP掉线
  2. MT6765开机LOGO图片的显示原理
  3. 计算机为何可以运行Java代码?
  4. You appear to be running an X server; please exit X before
  5. C++ 模板类的嵌套
  6. 锁相环(PLL),倍频器、分频器原理
  7. 微信小程序之知乎日报
  8. 信息发布服务器出问题,电力网故障信息发布系统
  9. 固定资产管理系统的作用和重要意义
  10. ms12-020漏洞