現(xiàn)在大家對(duì)爬蟲的興趣不斷高漲,R和PYTHON是兩個(gè)非常有力的爬蟲工具。Python傾向于做大型爬蟲,與R相比,語法相對(duì)復(fù)雜,因此Python爬蟲的學(xué)習(xí)曲線會(huì)相對(duì)陡峭。對(duì)于那些時(shí)間寶貴,又想從網(wǎng)上獲取數(shù)據(jù)的初學(xué)者而言,用R做爬蟲是最好的選擇,有三個(gè)原因:1、R語法相對(duì)直觀,規(guī)則更加靈活;2、對(duì)于數(shù)據(jù)量不大的用戶來數(shù)(小于百萬級(jí)),R也能夠非常自如地處理;3、先學(xué)習(xí)R爬蟲,等熟悉爬蟲的原理之后,在過渡到Python是很容易的。
這篇博文你會(huì)學(xué)到什么:
使用XML抓取表格數(shù)據(jù)(爬取勇士隊(duì)球員數(shù)據(jù))
使用rvest抓取網(wǎng)頁數(shù)據(jù)(爬取關(guān)于特朗普的百度新聞)
使用jsonlite抓取json格式數(shù)據(jù)(爬取高德地圖溫州各個(gè)行政區(qū)域的中心)
使用RSelenium模擬登錄抓取數(shù)據(jù)(模擬登錄人大經(jīng)濟(jì)論壇爬取R語言板塊數(shù)據(jù))
使用PhantomJS不登陸抓取數(shù)據(jù)(抓取國家數(shù)據(jù)各省的近13個(gè)月CPI)
另外你也會(huì)學(xué)到一些數(shù)據(jù)處理的小技巧
表格數(shù)據(jù)抓取
表格數(shù)據(jù)是最容易抓取的數(shù)據(jù)格式,直接使用XML包中的readHTMLTable函數(shù),一頁中的多個(gè)表格會(huì)使用列表的形式存儲(chǔ),在使用readHTNLTable的時(shí)候,header=T可以標(biāo)記出所抓取的表格是列名,大多說情況抓過來表格的列名是亂碼的,你可以使用rvest::repair_encoding對(duì)它們進(jìn)行修復(fù)。爬取勇士隊(duì)球員數(shù)據(jù)的代碼如下:
#抓取表格數(shù)據(jù)(抓取勇士隊(duì)的球員數(shù)據(jù))
library(XML)
url <- 'http://www./team/GSW.html'
dt1 <- readHTMLTable(url,header = T)
names(dt1[[1]]) <- rvest::repair_encoding(names(dt1[[1]]))
head(dt1[[1]])
球員 出場(chǎng) 首發(fā) 時(shí)間 投籃 命中 出手 三分 命中 出手 罰球 命中 出手 籃板
1凱文-杜蘭特 121234.753.8% 8.916.646.7% 2.96.386.9% 4.45.17.5
2斯蒂芬-庫里 131332.446.7% 7.516.238.8% 3.69.394.4% 6.56.84.7
3克萊-湯普森 131332.951.4% 8.516.547.1% 3.77.875.0% 0.50.63.8
4德雷蒙德-格林 131329.849.5% 3.57.035.7% 1.23.279.4% 2.12.67.9
5大衛(wèi)-韋斯特 12011.368.6% 2.94.375.0% 0.30.380.0% 0.70.82.3
6尼克-楊 12013.044.1% 2.24.941.7% 1.74.060.0% 0.30.41.0
前場(chǎng) 后場(chǎng) 助攻 搶斷 蓋帽 失誤 犯規(guī) 得分
10.86.84.90.62.43.42.325.2
20.54.26.71.80.22.62.225.2
30.53.42.70.70.81.82.221.1
41.16.86.71.01.33.23.010.2
51.01.31.30.71.41.41.66.8
60.30.80.90.80.10.41.16.3
rvest抓取網(wǎng)頁數(shù)據(jù)
rvest是R用戶使用率最多的爬蟲包,它簡(jiǎn)潔地語法可以解決大部分的爬蟲問題。它的使用方法比較固定1、使用read_html讀取網(wǎng)頁;2、通過CSS或Xpath獲取所需要的節(jié)點(diǎn)并使用html_nodres讀取節(jié)點(diǎn)內(nèi)容;3、結(jié)合stringr包對(duì)數(shù)據(jù)進(jìn)行清理。下面使用它爬取關(guān)于特朗普的百度新聞,具體代碼如下:
library(rvest)
library(stringr)
library(rlist)
url <- 'http://news.baidu.com/ns?cl=2&rn=20&tn=news&word=%E7%89%B9%E6%9C%97%E6%99%AE&ie=utf-8'
#抓取網(wǎng)頁
httr_web <- read_html(url,encoding = 'utf-8')
#抓取新聞標(biāo)題
title <- httr_web%>%html_nodes('h3>a')%>%html_text(trim = T)
#抓取新聞發(fā)布者與日期
author <- httr_web%>%html_nodes('p.c-author')%>%html_text(trim = T)
candidate_date=Sys.Date()%>%format('%Y年%m月%d日')
fun <- function(x){
re=if(length(x)==3){
re=c(x[1],candidate_date,x[length(x)])
}else{
re= x[-2]
}
re=data.frame(發(fā)布者=re[1],日期=re[2],時(shí)間=re[3])
return(re)
}
news_Trump <- data.frame(標(biāo)題=title ,
author%>%str_split('s')%>%lapply(fun)%>%list.stack())
tail(news_Trump)
標(biāo)題 發(fā)布者 日期 時(shí)間
15特朗普訪越車隊(duì)駛過河內(nèi)歌劇院 引眾人圍觀 網(wǎng)易 2017年11月12日 6小時(shí)前
16特朗普:美俄就政治解決敘利亞問題達(dá)成一致協(xié)議 環(huán)球網(wǎng) 2017年11月12日 9小時(shí)前
17英媒:印度為迎接特朗普女兒 圍捕乞丐暫住監(jiān)獄 騰訊新聞 2017年11月12日 14小時(shí)前
18【獨(dú)家】他此行的外交禮遇有點(diǎn)不一樣 環(huán)球網(wǎng) 2017年11月12日 7小時(shí)前
19得分“A+”的不止有特朗普外孫女,更有這支軍隊(duì) 中國軍網(wǎng) 2017年11月12日 6小時(shí)前
20多位專家談中美關(guān)系:兩國合作前景廣闊 中國新聞網(wǎng) 2017年11月12日 2小時(shí)前
抓取json格式數(shù)據(jù)
json數(shù)據(jù)是一些列數(shù)據(jù)的嵌套,它的一般格式如下 {key1:var1:{key2:var2,...},...}, 這種格式的數(shù)據(jù)通常為網(wǎng)站的開放數(shù)據(jù),可以申請(qǐng)目標(biāo)網(wǎng)站的API,然后獲取數(shù)據(jù)。獲得API后,rvest可以很容易處理這種數(shù)據(jù),但由于數(shù)據(jù)格式比較復(fù)雜,后期數(shù)據(jù)處理會(huì)有些繁瑣。因此這里建議大家使用jsonlite中的fromJSON函數(shù),它直接以嵌套列表的格式呈現(xiàn)數(shù)據(jù),不建議大家使用RJSON中的fromJSON,它你會(huì)的到url多重自字符的錯(cuò)誤。獲取高德地圖中溫州各行政區(qū)域中心坐標(biāo)的代碼如下,你也可使用這個(gè)方法獲取個(gè)行政區(qū)的json邊界,方法類似,這里不再說明。
##抓取JSON數(shù)據(jù)(抓取溫州各個(gè)行政區(qū)域的坐標(biāo))
library(jsonlite)
name='溫州'
encoding_name <- iconv(enc2utf8(name),from='utf-8',to='ISO-8859-1',sub= "byte")%>%
str_replace_all('><','%')%>%str_sub(1,18)%>%str_to_upper()%>%
str_replace('<','%')
subdistrict_num=1
key_str='你的API'
url0 <- 'http://restapi.amap.com/v3/config/district?'
url <- paste0(url0,
'keywords=',encoding_name,'&',
'subdistrict=',subdistrict_num,'&',
'key=',key_str)
wz_center<- fromJSON(url)
wz_centers<-wz_center[['districts']][['districts']][[1]]
tail(wz_centers)
citycode adcode name center level districts
60577330326平陽縣 120.565793,27.661918district NULL
70577330327蒼南縣 120.427619,27.519773district NULL
80577330328文成縣 120.091498,27.786996district NULL
90577330329泰順縣 119.717649,27.556884district NULL
100577330381瑞安市 120.655148,27.778657district NULL
110577330382樂清市 120.983906,28.113725district NULL
RSelenium模擬登錄抓取數(shù)據(jù)
使用RSelenium時(shí),你首先要下載Selenium,chromedriver,直接百度,這里不再說明。下載之后要把Selenium放在你當(dāng)前的工作目錄,chromedriver放在chorm的目錄下,win10用戶Altt+x--cmd---'>'前面的即為工作目錄,然后你還需要下載java,并把它放在你的環(huán)境變量中(注意區(qū)分用戶環(huán)境還是系統(tǒng)環(huán)境),最后在命令窗口輸入下面代碼: java -jar selenium-server-standalone-3.4.0.jar 上面命令運(yùn)行成功后我們就可已在R中使用RSelenium了,Selenium是一個(gè)模擬人點(diǎn)擊網(wǎng)頁的自動(dòng)化測(cè)試模塊,所有輸入和點(diǎn)擊的操作都可以用它實(shí)現(xiàn)。RSelenium的操作如下:
remoteDriver創(chuàng)建遠(yuǎn)程連接
open()打?yàn)g覽器
navigate(url)打開網(wǎng)頁
findElement、clickElement、sendKeysToElement三劍客進(jìn)行一些列的選中、點(diǎn)擊、輸入操作
getElementAttribute("outerHTML")[[1]]轉(zhuǎn)為HTML對(duì)象,然后使用rvest操作
library(RSelenium)
remDr <- remoteDriver(remoteServerAddr = "127.0.0.1",
port = 4444,
browserName = "chrome")
remDr$open() #打開瀏覽器
remDr$navigate('http://bbs./forum-69-1.html')
step1 <- remDr$findElement(using= 'xpath',
"http://*[@id='nv_forum']/div[6]/div[1]/div/div[4]/ul/li[3]/a")
step1$clickElement()
step21 <- remDr$findElement(using= 'xpath', '//*[@id="username"]')
step21$clickElement()
step21$sendKeysToElement(list(username ='用戶名'))
step22 <- remDr$findElement(using= 'xpath', '//*[@id="password"]')
step22$clickElement()
step22$sendKeysToElement(list(password ='密碼'))
step23 <- remDr$findElement(using= 'xpath', '/html/body/div[2]/div/div[2]/a')
step23$clickElement()
step3 <- remDr$findElement(using= "xpath","http://*[@id='moderate']/table")
web <- step3$getElementAttribute("outerHTML")[[1]]%>%read_html()
dat3=data.frame(
標(biāo)題=web%>%html_nodes('a.xst')%>%html_text(trim = T),
發(fā)布者=web%>%html_nodes('a.u')%>%html_text(trim = T),
發(fā)布時(shí)間=web%>%html_nodes('p>em>span')%>%html_text(trim = T),
最后回復(fù)者=web%>%html_nodes('p>em>a:nth-child(4)')%>%html_text(trim = T),
最后回復(fù)日期=web%>%html_nodes('p>em>a:nth-child(5)')%>%html_text(trim = T)
)
tail(dat3)
標(biāo)題
75R randomForest classification regression
76求教R語言中的MSBVAR包出現(xiàn)的問題
77【經(jīng)典教材系列】SpatialandSpatio-temporal BayesianModelswithR - INLA
78求助----關(guān)于R語言的randomforest包的一個(gè)問題
79用R繪制水平方向的條形圖并在相應(yīng)位置添加標(biāo)簽
80如何把散點(diǎn)和曲線花在一張圖上
發(fā)布者 發(fā)布時(shí)間 最后回復(fù)者 最后回復(fù)日期
75fengqifeng 2016-6-26魚鈴五校名22017-11-10
76xiaoqiang1789 2013-6-19涅墨西斯隨風(fēng) 2017-11-10
77wwqqer 2015-10-19苦丁冰茶 2017-11-10
78benbobo 2012-5-2魚鈴五校名22017-11-10
79慕目穆木 2017-11-9nkunku 2017-11-10
80awen1011 2017-11-2GOD.M.W 2017-11-10
使用PhantomJS不登陸抓取數(shù)據(jù)
首先下載phantomjs,然后把下面代碼塊復(fù)制到text,保存后更改后綴名為.js,若需要抓取其他js網(wǎng)頁,直接更改open中的內(nèi)容即可。注意你的到的js文件要和phantomjs.exe放在相同的工作目錄下。
// NDC.js
var webPage = require('webpage');
var page = webPage.create();
var fs = require('fs');
var path = 'NDC.html'
page.open('http://data.stats.gov.cn/easyquery.htm?cn=E0101', function (status) {
var content = page.content;
fs.write(path,content,'w')
phantom.exit();
});
運(yùn)行system("./phantomjs NDC.js")后,會(huì)在你的工作目錄下創(chuàng)建一個(gè)NDC.html文檔,直接用read_html讀就可以,然后獲取所需的表格數(shù)據(jù)。
system("./phantomjs NDC.js")
web <- read_html("NDC.html")
dat4 <- (web%>%html_table())[[1]]
tail(dat4)
地區(qū) 2017年9月 2017年8月 2017年7月 2017年6月 2017年5月 2017年4月
26西藏自治區(qū) 101.7101.5101.4101.2101.2101.3
27陜西省 102.2102.7102.1102.0101.8101.1
28甘肅省 102.1101.8101.4101.3100.8100.4
29青海省 102.3102.3101.6101.6101.099.8
30寧夏回族自治區(qū) 101.4101.6101.3101.7101.8101.3
31新疆維吾爾自治區(qū) 102.8101.9101.7102.1102.1101.5
2017年3月 2017年2月 2017年1月 2016年12月 2016年11月 2016年10月
26102.0102.4102.8103.0102.9102.7
27100.099.7101.5101.2101.5101.5
28100.2100.3101.7101.4101.2101.1
29100.1100.5102.0101.9102.0102.1
30100.7100.3102.6102.5102.3102.4
31101.2101.5102.8102.3102.4101.9
|