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("\r\n\r\n", $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("\r\n\r\n", $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("\r\n\r\n", $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();


?>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM