1、CURL小結php
我的將概括curl請求總結成三步服務器
一、建立curl 句柄(curl_init),並設置參數(curl_setopt)(打開冰箱)網絡
二、執行請求(curl_exec),處理返回的數據 (把大象塞進去)dom
三、關閉curl(curl_close),釋放全部資源(關上冰箱)curl
其實若是代碼看起來比較複雜,複雜的地方可能就是在處理返回數據的邏輯。函數
2、CURL_SETOPT網站
故名思議,SetOption 設置參數,其中囊括的參數較多,這裏只是簡單提取經常使用的幾個,如需查看更多參數,點擊這裏,常見的設置UA、Cookie、https等this
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頭,自行添加 url
curl_setopt($curl, CURLOPT_HEADER, 1);
判斷返回的狀態碼:spa
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(); ?>
3、分離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(); ?>
4、POST請求
POST請求無非比上述Get請求多設置了兩個參數。
一、嘿,我要用POST提交數據了。
二、我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); ?>
5、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(); ?>