1. 程式人生 > >RCurl中這麼多get函式,是不是一直傻傻分不清!!!

RCurl中這麼多get函式,是不是一直傻傻分不清!!!

0?wx_fmt=gif&wxfrom=5&wx_lazy=1

杜雨,EasyCharts團隊成員,R語言中文社群專欄作者,興趣方向為:Excel商務圖表,R語言資料視覺化,地理資訊資料視覺化。個人公眾號:資料小魔方(微信ID:datamofang) ,“資料小魔方”創始人。

你想知道R語言中的RCurl包中一共有幾個get開頭的函式嘛,今天我特意數了一下,大約有十四五個那麼多(保守估計)!

所以如果對這個包瞭解不太深入的話,遇到複雜的資料爬取需求,自然是摸不著頭腦,心碎一地~_~

實際上很多我們都不常用,常用的不超過五個,而且這些函式命名都很有規律,一般是類似功能的名稱中都有統一的關鍵詞標識,只要理解這些關鍵詞,很好區分,下面我對9個可能用到的get函式簡要做一個分類。

第一類是get請求函式(引數直接寫在URL裡面)

getURL              #get請求的一般形式
getBinaryURL        #get請求二進位制資源
getURLContent       #get請求(可以根據返回狀態的ContentType決定返回內容是文字格式還是二進位制格式,
                    #所以說它其實就是前兩個函式的結合體,可以根據返回內容型別做智慧判斷)
getURIAsynchronous  #這個函式文件給的解釋是可以實現請求的非同步傳送和多併發,需要計算機的cpu支援多核效能,至今尚未嘗試過!

以下兩個也是get請求函式(引數可以寫在單獨的查詢引數中)

getForm        #單獨提交查詢引數的get請求函式
getFormParams  可以根據帶引數的URL,分解出原始引數對

容錯與配置控制代碼函式

getCurlErrorClassNames  #排錯函式,可以根據請求錯誤資訊得到錯誤型別,方便後期排錯
getCurlHandle           #curl控制代碼函式(是請求回話維持與程序管理的最重要部分,所有登入操作、身份認證都都需要該函式的支援)
getCurlInfo             #根據curl控制代碼的記錄資訊,返回各專案資訊詳情

接下來我們逐個嘗試一遍上述函式的用法。

getURL

getURL函式是一個基礎get請求函式,其核心引數主要有URL、.opt、curl、.encoding。

  • URL就是請求的對應網址連結。

  • curl引數是一個控制代碼函式,它的引數指定物件是一個內嵌函式,通常是curl = getCurlHandle(),getCurlHandle()函式內同樣是配置資訊,不過curl控制代碼函式內的所有配置資訊是可以提供給全域性使用的,多次攜帶,維持整個回話狀態,相對於一組初始化引數,而.opt引數內的各項配置資訊是當前get請求使用的,它會覆蓋和修改curl控制代碼函式內的初始化資訊(當沒有提供.opt引數時,get請求仍然使用curl中的初始化引數。)

  • .opt是一個配置引數,它就收一組帶有命名的list引數,這些通常包括httpheader、proxy、timeout、verbose、cookiefile(cookiejar)等配置資訊。

  • .encoding是字符集編碼,這個通常可以通過請求的相應頭ContType獲取。

使用getURL傳送一個完整的請求一般形式是這樣的:

library("RCurl")
library("XML") debugInfo <- debugGatherer()    #錯誤資訊收集函式
headers<-c("User-Agent" = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36") ###curl控制代碼函式
handle <- getCurlHandle(                        debugfunction = debugInfo$update,                        followlocation = TRUE,                        cookiefile = "",                        verbose = T                        ) url<- "https://edu.hellobi.com/"
response<-getURL(
             url,                    ###URL地址
             #區域性配置引數(作用於本次請求)
             .opts=list(header=TRUE,httpheader = headers),
             curl=handle,           ###curl控制代碼,初始化配置引數(.opts內的宣告的配置引數會覆蓋curl中的預設引數)
             .encoding="utf-8"      ###編碼引數
             )

0?wx_fmt=jpeg

請求成功!

以上是getURL的一般形式,當然實際使用時,可以酌情調整引數,通常情況下,無需維持回話的話,curl不需要自己構造,函式會預設幫我們構造以個curl控制代碼。但是.opts引數使我們在當前請求中實際應用的配置引數資訊,需要特別注意。

cat(debugInfo$value()[1])  #伺服器地址及埠號
cat(debugInfo$value()[2])  #伺服器返回的相應頭資訊
cat(debugInfo$value()[3])  #返回的請求頭資訊

0?wx_fmt=jpeg

0?wx_fmt=jpeg
0?wx_fmt=jpeg

debugGatherer函式收集的請求與相應資訊對於後期的錯誤判斷與bug修復很有價值!

getBinaryURL

二進位制資源一般是指網路伺服器上的二進位制檔案、影象檔案、音視訊等多媒體檔案。這些資源通常可以直接通過download函式進行請求下載,但是getBinaryURL函式可以新增更多配置資訊,在 請求資源是更加安全。

url<-"https://pic3.zhimg.com/720845d4f960c680039dbf7cc83ec21a_r.jpg"
response<-getBinaryURL(url) writeBin(response,"720845d4f960c680039dbf7cc83ec21a_r.jpg")

0?wx_fmt=png下載到本地之後,開啟正常!

0?wx_fmt=jpeg

你可以使用%>%管道函式把兩句封裝在一起,使用起來非常方便,比自帶的download函式程式碼引數還少。除了圖片之外,csv檔案、xlsx檔案、pdf檔案、音視訊檔案都可以下載。

response<-getURLContent("https://pic3.zhimg.com/720845d4f960c680039dbf7cc83ec21a_r.jpg")
response<-getURLContent("https://edu.hellobi.com/")
class(response)
[1] "raw"
[1] "character"

使用getURLContent請求網頁時,返回的是字串(未解析的HTML文件),請求圖片時,反回的是bytes值。不那麼講究的場合,getURLContent可以替代getURL或者getBinaryURL,但是通常為了便於記憶,一般請求網頁使用getURL,請求二進位制檔案使用getBinaryURL,實際上三個函式僅僅是返回值的差異,通過引數設定的轉換,基本可以相互替代。

getURIAsynchronous函式執行執行多併發任務,具有非同步請求的功能,但是這一塊我還沒有研究透徹,至今尚未涉足,感興趣的小夥伴兒可以自己試一試,將請求URL作為一個多值向量,闖進去就可以了,勇於探索才能學到好玩的東西。

getForm

getForm傳送單獨攜帶查詢引數的get請求,這在之前的趣直播資料抓取中已經演示過了。

library("magrittr")
url<-"http://m.quzhiboapp.com/api/lives/listOrderByPlanTs"
header=c(
   "Accept"="application/json, text/plain, */*",
   "User-Agent"="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
) debugInfo <- debugGatherer() handle<-getCurlHandle(debugfunction=debugInfo$update,followlocation=TRUE,cookiefile="",verbose = TRUE) content<-getForm(url,.opts=list(httpheader=header),.params=list("limit"=30),.encoding="utf-8",curl=handle) %>% jsonlite::fromJSON() ###請注意這裡getForm函式與getURL函式的區別
###(多了一個.params引數,它就是用於存放get請求的引數的,getFrom可以提供專門的查詢引數)
head(content  %>% `[[`(2))

0?wx_fmt=jpeg

getFormParams

getFormParams函式可以還原URL中的查詢引數。

url<-"https://www.baidu.com/s?wd=writeBin&rsv_spt=1&rsv_iqid=0xe52332670003a3de&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&rsv_t=222fgx%2FjxyaSTATqTxa8ljEv1u8i5TvyENqvcB1Ku1QcP3ZUR2pqIQ2sntZFOTlA4NJx&oq=writeBin%2520%25E4%25B8%258B%25E8%25BD%25BD%25E5%259B%25BE%25E7%2589%2587&inputT=1300&rsv_sug3=13&rsv_pq=e9db342c0003c543&rsv_sug1=6&rsv_sug7=100&rsv_sug2=0&rsv_sug4=1940&rsv_sug=1"
getFormParams(url)

0?wx_fmt=jpeg

還原結果是一個帶有命名的字串向量。

getCurlErrorClassNames 函式是一個排錯函式,具體怎麼用我也不知道,目前還沒有用過,感興趣的自己探索!

0?wx_fmt=jpeg

getCurlHandle\getCurlInfo

getCurlHandle 函式是全域性的curl控制代碼函式,包含所有請求、相應以及本地終端與web伺服器之間的通訊記錄。它用於構建初始化配置函式。它通常與getCurlInfo 搭配使用。

debugInfo <- debugGatherer()    
#錯誤資訊收集函式
headers<-c("User-Agent" = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36") handle <- getCurlHandle(                        debugfunction = debugInfo$update,                        followlocation = TRUE,                        cookiefile = "",                        verbose = T                        ) url<- "https://edu.hellobi.com/"
response<-getURL(url,.opts=list(header=TRUE,httpheader = headers),curl=handle,.encoding="utf-8")

比如可以通過getCurlInfo 函式獲取handle中的所有資訊。

getCurlInfo(handle) %>% names()
cat(getCurlInfo(handle)$effective.url)
https://edu.hellobi.com/
cat(getCurlInfo(handle)$response.code)200cat(getCurlInfo(handle)$content.type)
text/html; charset=UTF-8cat(getCurlInfo(handle)$cookielist)
.hellobi.com    TRUE    /    FALSE    1511007061    XSRF-TOKEN    eyJpdiI6IkRLcndIcW0raVF3aDNkbjJRRVJwTHc9PSIsInZhbHVlIjoiRkFDMWdCdEJ4dGFOYTJBaWV2c3pHZm1IOHZoOW81eisxaFJENzJSRnVGXC9TQnZKTDRjZFQ3NlpicnVoODF3N0U3VTZuNXJHREtYbDR5SDc5YkREMGVnPT0iLCJtYWMiOiIzNWI2OTYyYWNlZmQwMDc1N2Q1Y2I5NTY4NzUxZWIzYWYwZDM0N2MzZmExMzQ1OGJlNDVjNmZiMzEwMWY4MjEwIn0%3D #HttpOnly_.hellobi.com    TRUE    /    FALSE    1511007061    laravel_session    eyJpdiI6Ik8zN3NUMjFjN2FRa1dldXZ4REhVTnc9PSIsInZhbHVlIjoiQ29kakpTRjFGdno5c2Y0elpSZWNhVFVpckJWTnRwaENaeHgxSThmOXRDNDU0T0k1djlUV011ZlBEQXV5N2drc3NBOHBzY0FWZEJSRG1ocjNweGpXNnc9PSIsIm1hYyI6IjZjOWRlMmNjMjg3MGM3MTEzZDA0N2M2OTdkNGUwYWM3MzY0N2MwNmJmYmMxZDAzYTllODEzZjQ0YWUzNjA4NjQifQ%3D%3D

0?wx_fmt=jpeg

好了,到這裡,RCurl的幾個重要get函式幾乎都已經講完了,接下來會抽時間整理一下RCurl的中postForm函式的四種常見引數提交方式,以及curl控制代碼函式配置引數的許可權型別,RCurl這個包經過這些時間的梳理,已經扒的差不多了,以後若是時間允許,可以探索一下RCurl中的併發與非同步請求實現方式。

其實除了RCurl之外,rvest包也有很多好玩的東西,最近的探索發現,rvest本身並不神奇,它作為一個底層請求器httr以及解析器selectr包、xml2包的封裝,整合了這些包的優點,在解析方面大有可為,但是請求功能上很薄弱,它的css解析器實現其實是在內部呼叫selectr包中的css_to_xpath函式,將css語法轉化為xpath之後才開始解析的,這樣如果你能花些時間學一下xml2\httr\selectr的話,幾乎可以完全繞過rvest包,自己靈活構建請求與解析函數了,這三個包文件都很少(httr稍多一些!)。

還計劃想寫一篇關於R爬蟲與Python對比的文章,R語言與Python在很多領域一直相愛相殺,Python的DataFrame貌似參考了R裡面的data.frame,並且移至了R語言中的ggplot2,而R語言中,哈德利寫的xml2包是由BeautifulSoup激發的的靈感,rvest包的初衷參照requests的框架,以後沒事兒多八卦一些R語言與Python背後的故事,感覺蠻好玩的!

線上課程請點選文末原文連結:
往期案例資料請移步本人GitHub:
https://github.com/ljtyduyu/DataWarehouse/tree/master/File

相關課程推薦

R語言爬蟲實戰案例分享:

網易雲課堂、知乎live、今日頭條、B站視訊

分享內容:本次課程所有內容及案例均來自於本人平時學習練習過程中的心得和筆記總結,希望藉此機會,將自己的爬蟲學習歷程與大家分享,併為R語言的爬蟲生態改善以及工具的推廣,貢獻一份微薄之力,也是自己爬蟲學習的階段性總結。

640?wx_fmt=png

☟☟☟ 戳閱讀原文,即刻加入課程。