rvest是R語(yǔ)言一個(gè)用來(lái)做網(wǎng)頁(yè)數(shù)據(jù)抓取的包蜈彼,包的介紹就是“更容易地收割(抓取)網(wǎng)頁(yè)”。其中html_nodes()函數(shù)查找標(biāo)簽的功能非常好用痹雅。以抓取天貓搜索結(jié)果頁(yè)的寶貝數(shù)據(jù)為例說(shuō)明rvest的使用蚀苛。
分析網(wǎng)頁(yè)
- 打開天貓在验,按F12鍵打開瀏覽器的開發(fā)工具。個(gè)人用的火狐堵未,誰(shuí)讓Chrom不支持linux了腋舌,唉。不過還是chrome好用啊渗蟹。其他瀏覽器都有類似的功能块饺。
- 隨便搜索個(gè)啥赞辩,比如核彈,我草還真出結(jié)果了授艰!
- 接下來(lái)辨嗽,在瀏覽器的開發(fā)工具"查看器"中查看網(wǎng)頁(yè)的源碼』刺冢或者按一下CTRL+SHIFT+C糟需,選擇任意寶貝」瘸可以看到寶貝的圖片洲押、月銷量等數(shù)據(jù)都是包含在<div class="product-iWrap">...</div>塊中的。
- 打開該div塊圆凰,哈哈杈帐,咱們需要的商品圖片、鏈接专钉、月銷量挑童、價(jià)格,以及商戶名稱等驶沼,都可以在里面找到了炮沐。話說(shuō),貓爹其實(shí)挺開放的回怜,沒有做太多限制大年,不然想抓這些數(shù)據(jù)就麻煩了。
接下來(lái)啟動(dòng)R玉雾,以下是用rvest包抓取寶貝數(shù)據(jù)的過程
- 安裝rvest包
install.packages("rvest")
- 加載rvest包
library(rvest)
- 保存搜索鏈接到對(duì)象gurl翔试,鏈接的拼接方式挺有規(guī)律的
gurl <- "https://list.tmall.com/search_product.htm?q=%C9%AD%B1%C8%B0%C2&type=p&vmarket=&spm=875.7931836%2FB.a2227oh.d100&from=mallfp..pc_1_searchbutton"
- 抓取數(shù)據(jù)保存到對(duì)象md中
- %>%是管道操作符,意思是把左邊的操作結(jié)果作為參數(shù)傳遞給右邊的命令
- div.product-iWrap 是CSS選擇器的語(yǔ)法复旬,即是 div class="div.product-iWarp"
md <- gurl %>%
read_html(encoding="GBK") %>% # 讀取gurl的鏈接垦缅,指定編碼為gbk
html_nodes("div.product-iWrap") # 篩選出所有包含在<div class="product-iWrap">...</div>塊的內(nèi)容
- 從對(duì)象md繼續(xù)篩選,獲賣家名稱等數(shù)據(jù)驹碍。
- html_attr("data-nick") 是從html_nodes()篩選出的標(biāo)簽中壁涎,查找data-nick屬性的值。
- gsub()是字符串查找替換的函數(shù)志秃,pattern是指定用來(lái)查找的正則表達(dá)式怔球。
- html_nodes("p.productTitle>a[title]"),”>"指定的篩選條件的父級(jí)標(biāo)簽。
- html_text() 只抓取<標(biāo)簽>內(nèi)容</標(biāo)簽>中的內(nèi)容部分浮还。
# 抓取賣家昵稱和ID
sellerNick <- md %>% html_nodes("p.productStatus>span[class]") %>%
html_attr("data-nick")
sellerId <- md %>% html_nodes("p.productStatus>span[data-atp]") %>%
html_attr("data-atp") %>%
gsub(pattern="^.*,",replacement="")
# 抓取寶貝名稱等數(shù)據(jù)
itemTitle <- md %>% html_nodes("p.productTitle>a[title]") %>%
html_attr("title")
itemId <- md %>% html_nodes("p.productStatus>span[class]") %>%
html_attr("data-item")
price <- md %>% html_nodes("em[title]") %>%
html_attr("title") %>%
as.numeric
volume <- md %>% html_nodes("span>em") %>%
html_text
# 最后保存成數(shù)據(jù)框?qū)ο蟛⒋姹P備用竟坛,以及寫入csv文件
options(stringsAsFactors = FALSE) # 設(shè)置字符串不自動(dòng)識(shí)別為因子
itemData <- data.frame(sellerNick=sellerNick,
sellerId=sellerId,itemTitle=itemTitle,
itemId=itemId,
price=price,
volume=volume)
save(itemData,file="F:/mydata/itemData.rData")
write.csv(itemData,file="F:/mydata/itemData.csv")
補(bǔ)充一個(gè)用rvest從趕集網(wǎng)抓取二手房單頁(yè)面數(shù)據(jù)的代碼
getData <- function(gurl){
# 抓取趕集網(wǎng)二手房源單頁(yè)的數(shù)據(jù)
library(rvest)
# 趕集網(wǎng)首頁(yè)篩選長(zhǎng)沙-雨花區(qū)-砂子塘的二手房源,獲得鏈接,o1為頁(yè)數(shù)
# gurl <- "http://cs.ganji.com/fang5/yuhuashazitang/o1/"
tmp <- gurl %>% html_session %>%
read_html(encoding="utf-8") %>%
html_nodes("div.f-main-list>div>div")
# 單個(gè)房源的puid
puid <- tmp %>% html_attr("id")
# 單個(gè)房源的鏈接
itemURL <-tmp %>% html_attr("href") %>%
gsub(pattern="/fang5",replacement="http://cs.ganji.com/fang5")
# 縮略圖鏈接
smallImg <- tmp %>% html_nodes("dl>dt>div>a>img") %>% html_attr("src")
# 標(biāo)題
iTitle <- tmp %>% html_nodes("dl>dd>a") %>% html_attr("title")
# 戶型
iLayout <- tmp %>% html_nodes("dl>dd[data-huxing]") %>% html_attr("data-huxing")
# 面積
iArea <- tmp %>% html_nodes("dl>dd[data-huxing]") %>%
html_attr("data-area") %>%
gsub(pattern="[^0-9]",replacement="")
# 篩選朝向等數(shù)據(jù)
iTmp <- tmp %>% html_nodes("dl>dd[data-huxing]>span") %>% html_text
iOrientation <- iTmp[seq(from=5,to=length(iTmp),by=9)] # 提取朝向
iFloor <- iTmp[seq(from=7,to=length(iTmp),by=9)] %>% # 提取樓層
gsub(pattern="\n",replacement="")
iDecoration <- iTmp[seq(from=9,to=length(iTmp),by=9)] # 提取裝修
# 提取地址
iAddr <- tmp %>% html_nodes("dl>dd>span.area") %>% html_text %>%
gsub(pattern="\n",replacement=" ") %>%
gsub(pattern=" ",replacement="")
# 提取價(jià)格
iPrice <- tmp %>% html_nodes("dl>dd>div.price>span:first-child") %>% html_text
# 提取單價(jià)
iTime <- tmp %>% html_nodes("dl>dd>div.time") %>% html_text %>%
gsub(pattern="[^0-9]",replacement="") %>% as.numeric
# 合并數(shù)據(jù)框
iData <- data.frame(puid=puid,
iLayout=iLayout,
iArea=iArea,
iPrice=iPrice,
iTime=iTime,
iDecoration=iDecoration,
iFloor=iFloor,
iOrientation=iOrientation,
itemURL=itemURL,
smallImg=smallImg,
iTitle=iTitle,
iAddr=iAddr,
stringsAsFactors=FALSE)
# 返回?cái)?shù)據(jù)框
return(iData)
}