1. 程式人生 > >網路資料抓取及其R實現(以鏈家樓盤為例)

網路資料抓取及其R實現(以鏈家樓盤為例)

本次資料抓取的鏈家新房樓盤,由於對網路抓取資料還不熟悉,所以現在只抓取了北京地區的樓盤。我在學習過程中主要參考資料為《基於R語言的自動資料收集》,這本書確實不錯,在前八章講解的基礎知識,以本書的配套網站資源為講解基礎,但是在按照書中抓取資料時有些地方和書本講的不太一樣,我認為主要是網路結構的變化引起的,大部分還是可行的。現在我看到了第九章,再往後都是一些網路資料抓取專案例項,所以後面的東西還需要認真學習.閒話少說,首先給出鏈家樓盤的連結.可以看一下原始碼原始碼
可以看出此處的原始碼還是比較清楚識別的。下面是資料抓取程式碼:

library(XML)
library(RCurl)
library(stringr)
library(tidyr)
library(dplyr)

url <- "http://bj.fang.lianjia.com/loupan/"
html_form <- getURL(url = url) parsed_form <- htmlParse(html_form) name <- xpathSApply(parsed_form,"//h2/a",xmlValue) area <- xpathSApply(parsed_form,"//div[@class = 'area']/span",xmlValue) #在area處只能用單引號括住,不能用雙引號,下同 onsold <- xpathSApply(parsed_form, "//div[@class='type']/span[@class='onsold']",xmlValue)
type <- xpathSApply(parsed_form, "//div[@class='type']/span[@class='live']",xmlValue) average <- xpathSApply(parsed_form, "//div[@class='average']/span[@class='num']",xmlValue) building <- cbind(name=name,area = area, onsold=onsold,live=type,average=average) buildings <- as.data.frame(building) ## cleaning the data
buildings_1 <- separate(data=buildings,col=area,into=c("a1","area"),sep=" ") buildings_1$a1 <- NULL buildings_2 <- separate(data=buildings_1,col=area,into=c("area"),sep="m2") buildings_2 <- separate(data=buildings_1,col=area,into=c("area","a"),sep="m") buildings_2$a <- NULL write.csv(buildings_2,"building.csv",row.names = F)

以上是我抓取的鏈家樓盤北京地區的第一頁資料,並把它儲存為building資料,但是下面我就遇到了一些麻煩,主要是在我寫入檔案時名稱是不變的,這樣前面已經寫入的檔案被後來的檔案所覆蓋了,可能是使用for迴圈也不合適,現在還沒有找到合適的辦法,如果有朋友知道更好的辦法的話,歡迎提出來,本人感激不盡。沒辦法我只能一個一個的來,幸好沒幾頁。下面是用最笨的辦法做的:

for(i in 2:2){ ##此處每次執行修改一下,從第2頁至第4頁手動修改(笨辦法)
  urls <- str_c(url, "pg", i ,"/")
  html_form <- getURL(url = urls)
  parsed_form <- htmlParse(html_form)
  name <- xpathSApply(parsed_form,"//h2/a",xmlValue)
  area <- xpathSApply(parsed_form,"//div[@class = 'area']/span",xmlValue)
  onsold <- xpathSApply(parsed_form, "//div[@class='type']/span[@class='onsold']",xmlValue)
  type <- xpathSApply(parsed_form, "//div[@class='type']/span[@class='live']",xmlValue)
  average <- xpathSApply(parsed_form, "//div[@class='average']/span[@class='num']",xmlValue)
  building <- cbind(name=name,area = area, onsold=onsold,live=type,average=average)
  buildings <- as.data.frame(building)
  ##cleaning data
  buildings_1 <- separate(data=buildings,col=area,into=c("a1","area"),sep=" ")
  buildings_1$a1 <- NULL
  buildings_2 <- separate(data=buildings_1,col=area,into=c("area"),sep="m2")
  buildings_2 <- separate(data=buildings_1,col=area,into=c("area","a"),sep="m")
  buildings_2$a <- NULL
  write.csv(buildings_2,"building2.csv",row.names = F) #此處building2.csv處需要手動修改,和上面修改的相對應(笨辦法)
}

##有一個辦法,可以按照下面來做,比如
a <- 0
for(i in 1:5){
a1 <- i
a <- c(a,a1) ##向a中新增值,先合併,最後整體分析

最後把資料合併,清理並分析

##merge data into "buildings".
buildings <- read.csv("building.csv")
buildings$average <- as.numeric(buildings$average)
building1 <- arrange(buildings,desc(average))
## plot data
ggplot(building1,aes(name,average,fill=name)) + 
  geom_bar(stat="identity") + coord_flip()
ggplot(building1,aes(average,fill=I("blue"))) + 
  geom_histogram() + 
  theme(panel.grid.major = element_blank())
ggplot(building1,aes(live)) + 
  geom_bar(aes(fill=live))
ggplot(building1,aes(live)) + 
  geom_bar(aes(fill=live)) + 
  coord_polar()

看一下整理後的資料
資料
在住房面積中,我沒有把最低與最高面積分開,如果要研究住房面積與其他變數的關係,可以把資料分開。
條形圖

1.
在畫圖的時候注意到,單位平方價格小於1000的都是萬元/每套,所以從圖上顯示有數值非常小的部分。從圖中可以看出,樓盤價格都在50000之上有8家,在100000之上(這可是單價呀)的有4家。北京真是待不起啊!奮鬥一年真心買不起一平廁所的。
直方圖
2.
從直方圖可以看出,樓盤價格是右偏的,看來北京新開的樓盤沒有價格低的,但是也可以看出大部分的樓盤25000及其以下,對比上述條形圖。50000之上的單價可能就是別墅了。
柱狀圖
3.
餅圖
4.
柱狀圖和餅圖可以看出住房類別,普通住宅和別墅佔大頭,商業類很少,這也說明北京有錢人真不少,要不然在這人稠地貴的帝都也不會出現這麼多別墅,竟然隱隱要趕上普通住宅了,要知道,別墅是最佔用地面積的。
先簡單分析到這,因為資料較少,無法深入分析,所以我還要繼續努力,爭取抓取多些資料。