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();
    
    
    ?>
  • 相关阅读:
    二分练习题4 查找最接近的元素 题解
    二分练习题5 二分法求函数的零点 题解
    二分练习题3 查找小于x的最大元素 题解
    二分练习题2 查找大于等于x的最小元素 题解
    二分练习题1 查找元素 题解
    code forces 1176 D. Recover it!
    code forces 1173 B. Nauuo and Chess
    code forces 1173 C. Nauuo and Cards
    吴恩达深度学习课程笔记-15
    吴恩达深度学习课程笔记-14
  • 原文地址:https://www.cnblogs.com/i0ject/p/7684923.html
Copyright © 2011-2022 走看看