zoukankan      html  css  js  c++  java
  • php之curl get post curl_multi_exec 请求用法

       一、CURL小结

             个人将归纳curl请求总结成三步

             1、创建curl 句柄(curl_init),并设置参数(curl_setopt)(打开冰箱)

             2、执行请求(curl_exec),处理返回的数据 (把大象塞进去)

             3、关闭curl(curl_close),释放所有资源(关上冰箱)

             其实如果代码看起来比较复杂,复杂的地方可能就是在处理返回数据的逻辑。

    二、CURL_SETOPT

            故名思议,SetOption 设置参数,其中囊括的参数较多,这里只是简单提取常用的几个,如需查看更多参数,点击这里,常见的设置UA、Cookie、https等

    bool curl_setopt          ( resource $ch , int $option , mixed $value )
    CURLOPT_USERAGENT         在HTTP请求中包含一个"User-Agent: "头的字符串。
    CURLOPT_REFERER           在HTTP请求头中"Referer: "的内容。
    CURLOPT_TIMEOUT           允许 cURL 函数执行的最长秒数。
    CURLOPT_RETURNTRANSFER    TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出。
    /*下面两个再https请求中才需设置*/ CURLOPT_SSL_VERIFYPEER
    FALSE 禁止 cURL 验证对等证书(peer's certificate)。要验证的交换证书可以在 CURLOPT_CAINFO 选项中设置,或在 CURLOPT_CAPATH中设置证书目录。(自cURL 7.10开始默认为 TRUE。从 cURL 7.10开始默认绑定安装。) CURLOPT_SSL_VERIFYHOST 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配。 0 为不检查名称。 在生产环境中,这个值应该是 2(默认值)。 值 1 的支持在 cURL 7.28.1 中被删除了。 

         如需返回的Header头,自行添加 

    curl_setopt($curl, CURLOPT_HEADER, 1);

         判断返回的状态码:

    curl_getinfo($curl, CURLINFO_HTTP_CODE)
    if(curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200')

         简单版的GET请求如下,下面以请求百度为例,只设置了最基本的属性:

    <?php
    $curl
    = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com'); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $sData = curl_exec($curl); curl_close($curl); var_dump($sData);
    ?>

           稍微复杂的设置了UA、Cookie等,https请求中才需要只用的SSL证书校验,http请求中可不用,如果需要请求有规律的地址,类似https://example.com/?id=$i,修改for循环即可。

    <?php
    
    class getRequest
    {
        const sUA = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
        const sURL = 'https://www.baidu.com';
        const sCookie = 'fake if you want';
    
        function vInitRequest()
        {
            $curl = curl_init();
    
            curl_setopt($curl, CURLOPT_HEADER, self::sUA);
            curl_setopt($curl, CURLOPT_COOKIE, self::sCookie);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    
            /*
             * ssl check,use for https url
             */
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
    
    //        for ($iId = 1; $iId < 1000; $iId++) {
    //            $sURL = self::sURL.$iId;
            curl_setopt($curl, CURLOPT_URL, self::sURL);
            $this->sExecRequest($curl);
    //        }
        }
    
    
        function sExecRequest($curl)
        {
            $sRet = curl_exec($curl);
            print_r($sRet);
            /**
             * handle your response
             * stripos or preg
             */
            curl_close($curl);
        }
    }
    
    $foo = new getRequest();
    $foo->vInitRequest();
    
    ?>

    三、分离Response里面的 Header和Body

          首先要显示Header信息需要设置,如下设置即可取到header和body,当然还有其他方法大同小异

    curl_setopt($curl, CURLOPT_HEADER, 1);
    list($sHeader, $sBody) = explode("
    
    ", $sRet, 2);

          完整代码:

    <?php
    
    class getRequest
    {
        const sUA = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
        const sURL = 'https://www.baidu.com';
        const sCookie = 'fake if you want';
    
        function vInitRequest()
        {
            $curl = curl_init();
            $i = 0;
            curl_setopt($curl, CURLOPT_HEADER, self::sUA);
            curl_setopt($curl, CURLOPT_COOKIE, self::sCookie);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HEADER, 1);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
            curl_setopt($curl, CURLOPT_URL, self::sURL);
            $this->sExecRequest($curl);
        }
    
    
        function sExecRequest($curl)
        {
            $sRet = curl_exec($curl);
            // if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200') {
                list($sHeader, $sBody) = explode("
    
    ", $sRet, 2);
            // }
                print_r($sHeader);
                print_r($sBody);
            // curl_close($curl);
        }
    }
    
    $foo = new getRequest();
    $foo->vInitRequest();
    ?>

    四、POST请求

          POST请求无非比上述Get请求多设置了两个参数。

          1、嘿,我要用POST提交数据了。

          2、我POST的数据的内容

    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, array('user'=>'test'));

          简单版如下:      

    <?php
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com');
    curl_setopt($curl, CURLOPT_HEADER, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    $aPostData = array(
      'username' => 'test',
       .....
    );
    curl_setopt($curl, CURLOPT_POSTFIELDS, $aPostData);
    $sData = curl_exec($curl);
    curl_close($curl);
    var_dump($sData);
    ?>

    五、curl_multi_exec请求

          curl_multi_exec可同时执行多个请求,如果你网络请求速度很快,网站相应的速度超过你处理Response的速度,建议采用curl_multi_exec,步骤很简单。代码如下

    curl_multi_init();//初始化
    curl_multi_add_handle()//添加句柄
    curl_multi_exec// 批量执行

         这里以爬取百度验证码图片为例:

    <?php
    ini_set("memory_limit", '-1');
    date_default_timezone_set("PRC");
    
    class multiGetRequest
    {
        const sUA = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
        const sURL = 'https://passport.baidu.com/cgi-bin/genimage?njGeb06e22aefd4de7a02671411de01f513c021a606ee0400d3';
        const sCookie = 'fake if you want';
        const sDir = '/Users/test/Desktop/baidu/'; //你自己的路径
        const iCurlCount = 100;    //爬取图片张数
        private $sMicrotime = '';
    
    
        function vInitMultiCurl()
        {
            $this->sMicrotime = microtime(true);
            $sMultiCurlResource = curl_multi_init();
            $this->vInitCurl($sMultiCurlResource);
        }
    
        function vInitCurl($sMultiCurlResource)
        {
            $i = 0;
            while ($i != self::iCurlCount) {
                $aCurlResource[$i] = curl_init(self::sURL);
                curl_setopt($aCurlResource[$i], CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($aCurlResource[$i], CURLOPT_HEADER, 1);
                curl_setopt($aCurlResource[$i], CURLOPT_TIMEOUT, 200);
                curl_multi_add_handle($sMultiCurlResource, $aCurlResource[$i]);
                $i++;
            }
            $this->vExecCurl($aCurlResource, $sMultiCurlResource);
        }
    
    
        function vExecCurl($aCurlResource, $sMultiCurlResource)
        {
            $iIsRunning = 0;
            do {
                $sMultiResource = curl_multi_exec($sMultiCurlResource, $iIsRunning);
                curl_multi_select($sMultiCurlResource);
            } while ($iIsRunning > 0 || $sMultiResource == CURLM_CALL_MULTI_PERFORM);
    
            foreach ($aCurlResource as $i => $rCurl) {
                $aRes[$i] = curl_multi_getcontent($rCurl);
            }
            $this->vHandleResponse($aRes);
        }
    
        function vHandleResponse($aRes)
        {
            var_dump(count($aRes));
            foreach ($aRes as $sReponse) {
                list($header, $body) = explode("
    
    ", $sReponse, 2);
                $sCode = strtotime(time()).rand(1,1000000);
                file_put_contents(self::sDir . $sCode . '.jpg', $body);
            }
            var_dump(('消时:' . round(microtime(true) - $this->sMicrotime, 3)));
        }
    
    }
    
    $foo = new multiGetRequest();
    $foo->vInitMultiCurl();
    
    
    ?>
  • 相关阅读:
    java jar 后台运行
    【Objective-C】内存管理
    GitHub Gist 指南
    模板发送java邮件
    JDK环境配置
    新装mysql数据库登陆不上去(账号密码正确)
    一个简单的爬取b站up下所有视频的所有评论信息的爬虫
    hexo Nunjucks Errors 解决方法
    新版正方教务系统导出课程表-油猴脚本
    ACM-图论-同余最短路
  • 原文地址:https://www.cnblogs.com/i0ject/p/7684923.html
Copyright © 2011-2022 走看看