R語言網路資料抓取的又一個難題,終於攻破了!
往期案例資料請移步本人GitHub:
https://github.com/ljtyduyu/DataWarehouse/tree/master/File
單純從資料抓取的邏輯來講(不談那些工程上的可用框架),個人覺得R語言中現有的請求庫中,RCurl和httr完全可以對標Python中的urllib和reuqests(當然py中在錯誤處理和解析框架上顯得更為專業!)。
我們經常使用的網路資料抓取需求,無非兩種:
要麼偽造瀏覽器請求
要麼驅動瀏覽器請求
對於偽造瀏覽器請求而言,雖然請求定義裡有諸多型別,但是實際上爬蟲用到的無非就是GET請求和POST請求。
而驅動瀏覽器就幾乎沒有什麼門檻了,所見即所得,R語言中的RSelenium/Rwebdriver和Python中的Selenium都可以完成(配置比較麻煩一些)。
GET請求的引數允許寫在URL裡,但是通常引數較多的情況下,直接拼url顯得非常不優雅,而RCurl,httr都提供了可選的GET請求提交方式。在RCurl裡,getURL通常用來完成不含引數的GET請求(或者引數直接拼在了URL裡),而getForm()函式通常用來完成含有引數的GET請求。(引數寫在param引數體中)。
httr中的GET函式同樣完成GET請求,query引數作為指定的請求引數提交方式(同樣可以選擇寫在URL裡)。
針對POST請求而言,作為API的普遍請求方式(也有一部分API是通過GET請求傳送的),POST請求灰常複雜,它的查詢引數必須含在請求體(body)中,而且引數傳送前需要做指定的編碼方式(就是request header中的content-type)。
長見的編碼方式有4種:
application/x-www-form-urlencoded
application/json
multipart/form-data
text/xml
如果你想深入理解這四種方式,可以參考以下兩篇文章,或者去看專業的http協議與瀏覽器相關內容。
http://www.cnblogs.com/111testing/p/6079565.html
https://bbs.125.la/thread-13743350-1-1.html
以上四種引數,我只實踐過前兩種,第三種需要上傳檔案,暫未遇到,第四種很少見。在RCurl包的POST函式中,只針對第一種、第三種做了顯式的引數宣告
style=httppost、post,但是第二種、第四種style引數中沒有列舉到。而httr在引數處理上顯得非常友好,直接指定了以上常見的四種方式:
要知道如今web前端中,使用json作為資料包返回的api實在是太普遍了,這個問題一直困擾著我,甚至一度認為RCurl包的POST方法不支援上傳json引數(可是RCurl是直接對接liburl這個通用的爬蟲C語言庫的,urllib也是,httr底層是用了RCurl的,httr能做到的RCurl自然不在話下)。
一定是作者把上傳json引數的方式隱藏了起來,或者是還沒有來得及封裝成高階函式,放在了底層,否則解釋不通。直到今天,瀏覽了linkedlin上面的一個大神寫的小品文,突然靈光乍現,趕緊一試,果然成功了!驗證了之前的想法,可能RCurl剛出道的時候,json還沒有成主流吧,所以json傳參沒有明顯的放在style這個POST方法的引數裡。而httr包則很討巧的把所有POST引數的編碼方式都宣告瞭(哈德利大神就是快人一步,造福人類)。http://www.linkedin.com/pulse/web-data-acquisition-structure-rcurl-request-part-2-roberto-palloni
以下是寫作本篇推送的目地,把利用RCurl包構造POST請求,以及提交json字串引數的案例及程式碼分享給大家。RCurl庫與httr相比,偏底層,函式多且繁瑣,httr更靈巧、輕便、簡潔。這種關係,像極了Python中的urllib和request。
構建報頭和查詢引數:
library("RCurl")
library("jsonlite")
library("magrittr")
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", "Content-Type"="application/json;charset=UTF-8", "Origin"="http://study.163.com", "edu-script-token"="3de0ac05e45a4c9693f2a3605fbfaede")
Cookies<- 'EDUWEBDEVICE=0e88ed7a9b8b4fc4bfc615e251aa8863; _ntes_nnid=833311d30eccaa9f26425affae2cfef1,1509630974190; _ntes_nuid=833311d30eccaa9f26425affae2cfef1; STUDY_CP_ENTRANCE_CLOSE=1; STUDY_MIND_TELBIND_CLOSE=1; promTips=1; NTESSTUDYSI=3de0ac05e45a4c9693f2a3605fbfaede; STUDY_INFO=oP4xHuM9V1uY_TRID1ZzHOm5mkJY|6|12769628|1510452481337; STUDY_SESS="ryW1kbDYUPDpeexx7xnRK3cGH1nUulhhGJ9D1qIzrgCuSgHl96KRz9xVAwMO6jui9A7L4BJ6hUaaPXVtLf+pWBMHJEw6UtuJtXPjl2yhevq6wVYQtAaJ+N+2maA3kITUrUnNZE+nE0TmYBoQFSEgOKEjUu22o4FQQjD/GeyPrqJsX8TS4muhOF/kd9duGihHABYarJu/gx1XyYYhTqa89g=="; STUDY_PERSIST="8e2epkzTa+8Xy6agY2FPkUzktd9F+8CZ1rZxShzQSSRJ6RbRK2pSzoTqPic7hOB7dYsCtyfpIAD9Ue4S1oRerMBML+fd8iksmANh7THsUTBAXY6WM4kHXJFcNuERKuWuDeHOMilu1y+7T3/a7Jav0QPXrTaWx6YerFKJia2+3rEucY6CQ9waCFR9bhYObYkE6X9kJ71ahCvMYtkr9eXcE6s1rFdKOIgMEtQwxl1Jb8oli9XIBhsosLWHLIUZIfzGwHfmjuVpkfHAfiCIxUJfLiv82sP6EP+Q6n6O/pIeGx0="; STUDY_MIND_TELBIND=1; NETEASE_WDA_UID=12769628#|#1451204764916; NTES_STUDY_YUNXIN_ACCID=s-12769628; NTES_STUDY_YUNXIN_TOKEN=da46d92b7a9504736f2534ed1d366296; STUDY_NOT_SHOW_PROMOTION_WIN=true; utm="eyJjIjoiIiwiY3QiOiIiLCJpIjoiIiwibSI6IiIsInMiOiIiLCJ0IjoiIn0=|aHR0cDovL3N0dWR5LjE2My5jb20vY291cnNlcy1zZWFyY2g/a2V5d29yZD0lRTUlODglOTglRTUlODclQUY="; __utma=129633230.621520113.1509630968.1510452483.1510452504.13; __utmb=129633230.12.9.1510455608393; __utmc=129633230; __utmz=129633230.1509630968.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'headers['Cookie']<-Cookies
Payloads=list(
"pageIndex"=1,
"pageSize"=50,
"relativeOffset"=0,
"frontCategoryId"="400000000158033",
"searchTimeType"=-1,
"orderType"=0,
"priceType"=-1,
"activityId"=0
)
構建自動抓取函式:
GetCourses<-function(url,header=headers,Payload=Payloads){
fullinfo <- data.frame()
d <- debugGatherer()
handle <- getCurlHandle(debugfunction=d$update,followlocation=TRUE,cookiefile="",verbose = TRUE)
for (i in 1:17){
Payload[['pageIndex']]=i
Payload[['relativeOffset']]=50*i-50
tryCatch({
content <- postForm(url,.opts=list(postfields=toJSON(Payload,auto_unbox=TRUE),httpheader=header),.encoding="utf-8",curl=handle)
###通過將post需求提交的引數編碼為json字串,封裝在postForm函式的配置引數.opts中,完成json查詢引數的傳遞!,
###竟然不寫在style裡,搞得人暈頭轉向的!注意使用toJSON序列化的時候,auto_unbox要設定為TRUE,否則預設為TRUE,單值都會被包括成列表!
response <- content %>% fromJSON() %>% `[[`(3) %>% `[[`(2)
fullinfo <- response %>% rbind(fullinfo,.)
cat(sprintf("第【%d】頁已抓取完畢!",i),sep = "\n")
},error = function(e){
cat(sprintf("第【%d】頁抓取失敗!",i),sep = "\n")
})
Sys.sleep(runif(1))
}
cat("all page is OK!!!")
return (fullinfo)
}
#執行函式
url<-'http://study.163.com/p/search/studycourse.json'
myresult<- GetCourses(url)
#預覽資料
DT::datatable(myresult)
至此,R語言中的兩大資料抓取神器(請求庫),RCurl+httr,針對主流的GET請求、POST請求(常用的)都已經完成探索和案例輸出。以後的案例會不斷補充一些高階的反反爬技巧!
備註:以上header中的cookie是防止請求被瀏覽器遮蔽,edu-script-token引數是程式的token,你可以理解為類似祕鑰的東西,所以如果想要實踐本篇內容,以上兩個引數需要你從自己的Chrome中提取,直接執行本篇程式碼估計不大可能出資料!
相關課程推薦
R語言爬蟲實戰案例分享:
網易雲課堂、知乎live、今日頭條、B站視訊
分享內容:本次課程所有內容及案例均來自於本人平時學習練習過程中的心得和筆記總結,希望藉此機會,將自己的爬蟲學習歷程與大家分享,併為R語言的爬蟲生態改善以及工具的推廣,貢獻一份微薄之力,也是自己爬蟲學習的階段性總結。
☟☟☟ 猛戳閱讀原文,即刻加入課程。
相關文章
- 又一個基於JVM的程式語言:FlixJVM
- 社交網路分析的 R 基礎:(一)初探 R 語言
- R語言批量建立資料框R語言
- 資料分析與R語言01R語言
- R語言資料處理(一)R語言
- r語言資料處理(三)R語言
- R語言資料質量分析R語言
- 基於R語言的跨平臺大資料機器學習與資料分析系統R語言大資料機器學習
- 又一個全新程式語言,誕生了!
- R語言連線資料庫(MySQL)R語言資料庫MySql
- R語言入門與資料分析R語言
- 【R語言入門】R語言中的變數與基本資料型別R語言變數資料型別
- R語言實戰(1) 資料集的建立R語言
- R語言批量提取excel當中的資料R語言Excel
- Python網路抓取的三個常見問題Python
- 關於成立英語資料抓取組的倡議
- python和R語言哪個好?哪個適合資料分析?PythonR語言
- [譯] Scratch 平臺的神經網路實現(R 語言)神經網路
- R語言學習-高階資料管理R語言
- R語言:資料輸出至檔案R語言
- R語言資料處理(二)字元分隔R語言字元
- 爬蟲抓取網路資料時經常遇到的六種問題爬蟲
- r語言R語言
- 《R語言入門與資料分析》——向量索引R語言索引
- 網路語言
- 英語資料抓取組的章程
- 【R語言入門】R語言環境搭建R語言
- 爬取網頁後的抓取資料_3種抓取網頁資料方法網頁
- 資料洩露將成為最大的網路攻擊問題
- R語言基於表格檔案的資料繪製具有多個系列的柱狀圖與直方圖R語言直方圖
- C語言將資料表輸出到終端C語言
- 資料分析與挖掘 - R語言:KNN演算法R語言KNN演算法
- 精選 | 你必須懂的R語言最新資料包R語言
- R 語言使用
- PHP語言終於有了正式的規範PHP
- R語言資料探勘中的,“迴歸分析”是如何操作的?R語言
- 【譯文】R語言網路爬蟲初學者指南(使用rvest包)R語言爬蟲
- 古語與網路語言