PHP使用CURL抓取网页
来源:互联网 发布:网络公开课的好处 编辑:程序博客网 时间:2024/04/30 07:28
CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。
使用CURL的PHP扩展完成一个HTTP请求的发送一般有以下几个步骤:
- 初始化连接句柄;
- 设置CURL选项;
- 执行并获取结果;
- 释放CURL连接句柄。
$curl=curl_init(); //初始化curl句柄$url="http://www.conglinfeng.com/together/detail.php?show_ID=5"; //要请求的url地址curl_setopt($curl, CURLOPT_URL,$url); //设置curl的参数,即要请求的url是$urlcurl_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/htmlcurl_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抓取网页
- PHP使用CURL抓取网页
- 使用PHP的cURL库进行网页抓取
- PHP使用cURL抓取数据
- PHP cURL用法(抓取网页)
- php中的curl 网页抓取函数
- CURL多线程抓取网页
- curl抓取https网页
- 结合PHP和CURL抓取远程网页数据
- php curl 抓取网页的介绍和推广
- php cURL库(抓取网页,post数据及其他)
- php curl与正则表达式抓取网页数据的例子
- (PHP)用cURL抓取网页信息并替换部分内容
- curl设置不当导致php抓取网页失败
- PHP采用curl多线程抓取网页功能实现
- php curl 多线程抓取
- php curl 抓取数据
- 使用curl模拟登陆抓取网页指定内容
- 进程的常用调度算法
- java中常见异常
- [C++基础]003_注释
- 第4周项目5-猴子选大王
- C++日期类的实现
- PHP使用CURL抓取网页
- c语言入门 输出乘法口诀表
- hdu 4460 -最短路径
- 题目1486:False coin
- XPC U盘启动盘的制作
- 精确计算时,不要使用float或double
- CoordinatorLayout+AppBarLayout的使用
- Spark项目
- error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]