這篇文章主要介紹了php采集神器cURL怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
成都創(chuàng)新互聯(lián)公司是網(wǎng)站建設技術企業(yè),為成都企業(yè)提供專業(yè)的成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設,網(wǎng)站設計,網(wǎng)站制作,網(wǎng)站改版等技術服務。擁有十載豐富建站經(jīng)驗和眾多成功案例,為您定制適合企業(yè)的網(wǎng)站。十載品質(zhì),值得信賴!對于做過數(shù)據(jù)采集的人來說,cURL一定不會陌生。雖然在PHP中有file_get_contents函數(shù)可以獲取遠程鏈接的數(shù)據(jù),但是它的可控制性太差了,對于各種復雜情況的采集情景,file_get_contents顯得有點無能為力。因此,本文將為你介紹采集神器cURL的使用。
先給大家補充一下file_get_contents函數(shù)可以獲取遠程鏈接數(shù)據(jù)的方法。
這段代碼會直接使用curl顯示文件內(nèi)容,但是問題來了,因為curl是php的擴展,有的主機為了安全會金庸curl的,寧外php本地調(diào)試的時候也是關閉curl的,所以會發(fā)生報錯,所以這段代碼是不可取的,所以云落對他重新改寫了
修改后的版本是對curl擴展做一個判斷,看看服務器到底有木有打開curl擴展,如果打開了,就直接顯示文件,如果沒打開就顯示一段提示文字。
雖然修復了問題,但是又有一個問題來了,我只是顯示一段文字而已,我也不是是用什么做什么大事的,所以我為什么要寫那么多的代碼呢??
經(jīng)過一些瞎掰的檢測,發(fā)現(xiàn)file_get_contents獲取遠程文件內(nèi)容的速度不比curl慢,在一些文件較少的情況下可能還比curl擴展要快得多,所以我又重寫了代碼
工具
火狐瀏覽器(FireFox) + Firebug
“工欲善其事,必先利其器?!?在分析案例之前,先讓我們學習一下如何利用神器Firebug獲取我們必要的信息。
使用F12打開Firebug,我們可以得到如圖(一)界面:
1、箭頭圖標是“元素選擇”工具,單擊一次會高亮圖標,同時,鼠標在頁面內(nèi)的移動會同時在HTML菜單中選定相應的內(nèi)容,此時單擊內(nèi)容則表示選定了該元素,圖標高亮取消。如圖(二)所示:
Firebug查看元素
2、控制臺
JS里面的console.log系列函數(shù)的打印就是在這里輸出。
3、HTML
HTML內(nèi)容,注意這里看到的不一定是采集要解析的內(nèi)容,采集時候?qū)?nèi)容的分析,一律以查看源碼(Ctrl+U)為準,這里只是能快速定位元素的結構,然后再選擇一個比較特殊的參照,在源碼中定位相應的位置。
比如,你在HTML里面看到一個標簽是
另外,火狐還有一款 Tamper data 擴展也能得到請求數(shù)據(jù),必要時可以安裝使用。
8、Cookies
Cookie數(shù)據(jù)
在圖(一)中還看到下面有很多可選的小菜單項,其中保持是我們要關注的,當選擇它的時候,即使提交表單刷新了頁面,下面內(nèi)容區(qū)域的數(shù)據(jù)還是會保留,這個對于分析提交數(shù)據(jù)特別關鍵。
總結
我們在分析采集請求的時候,主要關心“網(wǎng)絡”菜單里的請求數(shù)據(jù),必要時候使用“保持”以查看刷新頁面的請求數(shù)據(jù),請求前可以使用“清除”先清除下面的內(nèi)容。
案例解析
一、簡單的采集
這里所指的簡單采集,是指一個單一頁面GET請求的采集,它簡單得即使通過file_get_contents函數(shù)也能輕松獲得頁面返回結果。
代碼片段之file_get_contents
代碼片段之cURL
二、需要參數(shù)的采集
這種情況,頁面請求需要傳入一些參數(shù),可以是GET請求,也可以是POST請求。這種情況的采集,使用file_get_contents外帶一些參數(shù)還是可以實現(xiàn)的,但是這里我們將不再展示。代碼片段之cURL GET
這種請求,我們可以選擇搜索引擎作為演示,比如我百度搜索一個詞語“PHP cURL”,在輸入回車后,我們會得到一個類似http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&ch=&tn=baidu&bar=&wd=PHP%20cURL的鏈接,注意這里的鏈接可能不同瀏覽器、不同入口方式訪問得到不一樣結果,因此不必介意鏈接是否一樣。通過輸入多個關鍵詞并觀察鏈接,我們可以確定 wd 參數(shù)就是我們要傳入的動態(tài)參數(shù),而其他參數(shù)則可以不變,因此得到我們下面的采集代碼。有些時候,一些參數(shù)并不是必須的,這時候我們可以刪掉它,比如上面的鏈接可以只保留http://www.baidu.com/s?ie=utf-8&wd=PHP%20cURL,ie=utf-8 這個參數(shù)可能影響結果的編碼,所以暫且留著它。就這樣簡單的代碼,我們就可以采集到百度搜索的結果了。
代碼片段之cURL POST
對于POST類型的請求,我們平時并不少見,比如有些搜索就是使用POST方式提交,這時候我們就需要使用POST類型來提交參數(shù)了。這個在PHP cURL里面有相應的參數(shù):CURLOPT_POST 和 CURLOPT_POSTFIELDS , CURLOPT_POST 的設置可以指定當前提交是否為POST方式,CURLOPT_POSTFIELDS則用于設定提交的參數(shù),可以是參數(shù)串,也可以是參數(shù)數(shù)組,比如:curl_setopt($ch, CURLOPT_POSTFIELDS, 'ie=utf-8&wd=PHP%20cURL'); 或 curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'ie' => 'utf-8', 'wd' => 'PHP%20cURL', ));下面是我做的一個POST模擬搜索PHP POST 搜索,后端是使用了前面的百度關鍵詞搜索,基本原理就是,客戶端提交一個關鍵詞到我服務器,我服務器使用該關鍵詞請求百度的搜索,然后得到結果,返回到客戶端。
如圖(四)是利用Firebug對請求數(shù)據(jù)的分析,得到我們需要提交的請求鏈接和請求參數(shù):然后下面是我們的代碼:
urlencode($keyword), ); $url = 'http://demo.zjmainstay.cn/php/curl/search.php'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回數(shù)據(jù)不直接輸出 curl_setopt($ch, CURLOPT_POST, 1); //發(fā)送POST類型數(shù)據(jù) curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //POST數(shù)據(jù),$post可以是數(shù)組,也可以是拼接 $content = curl_exec($ch); //執(zhí)行并存儲結果 curl_close($ch); var_dump($content);三、需要Referer的采集
對于一些程序,它可能判斷來源網(wǎng)址,如果發(fā)現(xiàn)referer不是自己的網(wǎng)站,則拒絕訪問,這時候,我們就需要添加CURLOPT_REFERER參數(shù),模擬來路,使得程序能夠正常采集。urlencode($keyword), ); $url = 'http://demo.zjmainstay.cn/php/curl/search_refer.php'; $refer = 'http://demo.zjmainstay.cn/'; //來路地址 $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回數(shù)據(jù)不直接輸出 curl_setopt($ch, CURLOPT_REFERER, $refer); //來路模擬 curl_setopt($ch, CURLOPT_POST, 1); //發(fā)送POST類型數(shù)據(jù) curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //POST數(shù)據(jù),$post可以是數(shù)組,也可以是拼接 $content = curl_exec($ch); //執(zhí)行并存儲結果 curl_close($ch); var_dump($content);search_refer.php的源碼如下,做了簡單的Referer判斷攔截:
四、需要cookie支持的采集
對于模擬登錄的應用,單單提交參數(shù)和模擬來路并不能解決問題,這時候我們就需要保存或者提交相應的Cookie參數(shù),這個在PHP cURL里面也提供了相應的參數(shù):
CURLOPT_COOKIE: 直接使用字符串方式提交cookie參數(shù)
CURLOPT_COOKIEFILE: 使用文件方式提交cookie參數(shù)
CURLOPT_COOKIEJAR: 保存提交后反饋的cookie數(shù)據(jù)下面是PHP100的模擬登錄示例:
五、壓縮網(wǎng)頁采集(gzip)
有些沒有接觸過壓縮頁面的朋友估計會在這里被坑死,因為他們會發(fā)現(xiàn)采集回來的內(nèi)容是亂碼,并且無論使用iconv還是強大的mb_convert_encoding都無法還原數(shù)據(jù),然后又沒有概念,各種抓狂卻找不到方法,哈哈,我曾經(jīng)也是這樣~
如圖(五)是亂碼表現(xiàn)形式:還好最后功夫不負有心人,還是找到了,它就是CURLOPT_ENCODING參數(shù)。
比如,采集搜狐的新聞時候就遇到gzip壓縮問題,下面是示例:手冊說明:支持的編碼有"identity","deflate"和"gzip"。如果為空字符串"",請求頭會發(fā)送所有支持的編碼類型。
后面一句表明,使用curl_setopt($ch, CURLOPT_ENCODING, "");也是可以的,但是不能不加這個參數(shù)。六、SSL鏈接的采集
有些請求鏈接是https類型的,這時候使用cURL采集可能會失敗,這時候,我們可以使用 var_dump(curl_error($ch));的方法打印錯誤提示,然后根據(jù)錯誤提示查找相應的解決方案。比如SSL錯誤常見提示:SSL certificate problem: unable to get local issuer certificate,這時候,我們就需要利用參數(shù):CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST 來禁用SSL證書的驗證,我嘗試過只使用CURLOPT_SSL_VERIFYPEER參數(shù)禁用失敗,所以大家好同時使用兩個參數(shù)。
下面是代碼示例:七、代理采集
大家都知道,國內(nèi)存在萬惡的墻,所以,假如我們需要獲取某些被墻數(shù)據(jù)時,就需要用到國外代理服務器;又或者我們需要采集大量數(shù)據(jù)時,需要不斷切換IP,也會用到代理。
使用代理在PHP cURL里面有幾個相對應的參數(shù):CURLOPT_PROXY、CURLOPT_PROXYPORT 和 CURLOPT_PROXYUSERPWD,還有另外幾個,這里不列舉。
CURLOPT_PROXY 指定代理IP參數(shù)
CURLOPT_PROXYPORT 指定代理端口參數(shù)
CURLOPT_PROXYUSERPWD 指定需要驗證的代理的賬號密碼,"[username]:[password]"格式的字符串關于代理賬號獲取,大家自己發(fā)揮,我這里提供網(wǎng)上搜索到的一個列表:cURL 高匿代理
下面是代理采集示例:
八、 多線程采集
對于大量采集工作,為了提高采集效率,使用PHP cURL提供的多線程采集是必不可少的。手冊上提供的多線程采集例子好像都不太好用,我剛開始也從里面測試了幾個例子,但是發(fā)現(xiàn)都是執(zhí)行卡死,根本無法執(zhí)行完成,前幾天突然又測試了一下,然后發(fā)現(xiàn)curl_multi_info_read函數(shù)下面的Example #1是可以執(zhí)行的,它的內(nèi)容在$res上,但是沒有打印出來,而且雅虎的請求比較慢,會卡住,前面兩個鏈接都能正常返回。
不過,還好當時的例子不好用,然后我經(jīng)過搜索找到了一個很厲害的項目,CurlMulti ,它對PHP cURL Multi 進行了一個良性擴展的封裝,能夠很好地提供采集支持。
關于CurlMulti的使用我就不多介紹,官網(wǎng)上面提供了demo,使用過程有技術難題可以直接加入Q群討論,作者@Ares 和其他的采集大牛都會提供技術解答幫助。
下面是PHP cURL Multi的一個簡單示例:$url) { $conn[$i] = curl_init($url); curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1); //不直接輸出結果 curl_multi_add_handle($mh, $conn[$i]); } $active = null; $res = array(); do { $status = curl_multi_exec($mh, $active); $info = curl_multi_info_read($mh); if (false !== $info) { //采集信息處理 $res[] = array( 'content' => curl_multi_getcontent($info['handle']), 'info' => $info, ); curl_close($info['handle']); } } while ($status === CURLM_CALL_MULTI_PERFORM || $active); curl_multi_close($mh); var_dump($res);九、302跳轉(zhuǎn)(301跳轉(zhuǎn))
對于一些應用,比如模擬登錄,如果遇上302跳轉(zhuǎn),會導致cookie丟失而使得模擬登錄失敗,請求現(xiàn)象如圖(六)所示:這個時候,可以使用:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);關于CURLOPT_FOLLOWLOCATION,手冊說明是:
啟用時會將服務器服務器返回的"Location: "放在header中遞歸的返回給服務器,使用CURLOPT_MAXREDIRS可以限定遞歸返回的數(shù)量。
我個人理解,通俗點講就是后面的跳轉(zhuǎn)會繼續(xù)跟蹤訪問,而且cookie在header里面被保留了下來。十、模擬上傳文件
在PHP手冊的curl_setopt函數(shù)中,關于CURLOPT_POSTFIELDS有如下描述:全部數(shù)據(jù)使用HTTP協(xié)議中的"POST"操作來發(fā)送。要發(fā)送文件,在文件名前面加上@前綴并使用完整路徑。這個參數(shù)可以通過urlencoded后的字符串類似'para1=val1¶2=val2&...'或使用一個以字段名為鍵值,字段數(shù)據(jù)為值的數(shù)組。如果value是一個數(shù)組,Content-Type頭將會被設置成multipart/form-data。對于上傳文件,這句話包含兩個信息:
1. 要上傳文件,post的數(shù)據(jù)參數(shù)必須使用數(shù)組,使得Content-Type頭將會被設置成multipart/form-data。
2. 要上傳文件,在文件名前面加上@前綴并使用完整路徑。
因此,模擬文件上傳可以按照如下實現(xiàn)://上傳D盤下的test.jpg文件,文件必須存在,否則curl處理失敗且沒有任何提示 $data = array('name' => 'Foo', 'file' => '@d:/test.jpg'); $ch = curl_init('http://localhost/upload.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_exec($ch);本地測試的時候,在upload.php文件中打印出\\(_POST和\$_FILES即可驗證是否上傳成功,如下: ``` print_r($_FILES);
輸出結果類似:
Array ( [name] => Foo ) Array ( [file] => Array ( [name] => test.jpg [type] => application/octet-stream [tmp_name] => D:\xampp\tmp\php2EA0.tmp [error] => 0 [size] => 139999 ) )關于CURLOPT_POSTFIELDS的賦值,另外補充一句描述:
傳遞一個數(shù)組到CURLOPT_POSTFIELDS,cURL會把數(shù)據(jù)編碼成 multipart/form-data,而然傳遞一個URL-encoded字符串時,數(shù)據(jù)會被編碼成 application/x-www-form-urlencoded。即:
curl_setopt(\(ch, CURLOPT_POSTFIELDS, 'param1=val1¶m2=val2&...'); 和 curl_setopt(\)ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));感謝你能夠認真閱讀完這篇文章,希望小編分享的“php采集神器cURL怎么用”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設公司,,關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!
分享標題:php采集神器cURL怎么用-創(chuàng)新互聯(lián)
URL地址:http://weahome.cn/article/djjodg.html