1 问题描述
二手房的信息往往在一个网页中以列表的形式展示多条信息,甚至存在多页的信息。只要是静态网页,那么我们依然可以采用rvest包来爬取信息!
首先,我们先提取一个页面上的二手房信息,接在再采用循环语句来提取多页的二手房信息。
2 爬取贝壳找房的二手房信息
2.1 爬取一个页面上的二手房信息
加载rvest包
> library(rvest) #解析网页
> library(tidyverse) #处理字符串
定义该网页的网址
> url='https://bj.ke.com/ershoufang/'
采用read_html()函数解析该网页
> web=read_html(url,encoding = 'utf-8')
爬取二手房的标题
可以使用chrome等浏览器的"检查元素"功能。然后点击下图中红色区域图标!
之后鼠标移到需要提取信息的网页位置,浏览器会自动给出该内容的节点位置:a.VIEWDATA.CLICKDATA.maidian-detail
> web %>% html_nodes('a.VIEWDATA.CLICKDATA.maidian-detail') %>% html_text() %>% str_remove_all("\\n") %>% str_remove_all(" ")
[1] ""
[2] "东三环弘善家园高楼层两居室诚意出售"
[3] ""
[4] "龙跃苑四区2室1厅南北"
[5] ""
[6] "北京方向2室1厅南西北"
说明:原始网页中图片和标题节点位置一样,所以每个标题前面多了一行空值。这里仅显示了前6行。
爬取标题后去除前面的空行
> title=web %>% html_nodes('a.VIEWDATA.CLICKDATA.maidian-detail') %>% html_text() %>% str_remove_all("\\n") %>% str_remove_all(" ")
> title=title[-which(title=="")]
> head(title)
[1] "东三环弘善家园高楼层两居室诚意出售"
[2] "龙跃苑四区2室1厅南北"
[3] "北京方向2室1厅南西北"
[4] "磨房南里西南一居带装修明厨明卫预约看房视野好"
[5] "中关村东大院经典两居室精装修随时看房"
[6] "丽景长安南北通透三居室高楼层精装修"
说明:采用which(title=="")判断空行的位置并删除!
采用html_attr()函数爬取标题的链接(属性)
> linkaddr=web %>% html_nodes('a.VIEWDATA.CLICKDATA.maidian-detail') %>% html_attr("href")
> head(linkaddr)
[1] "https://bj.ke.com/ershoufang/101114885764.html"
[2] "https://bj.ke.com/ershoufang/101114885764.html"
[3] "https://bj.ke.com/ershoufang/101114884149.html"
[4] "https://bj.ke.com/ershoufang/101114884149.html"
[5] "https://bj.ke.com/ershoufang/101114882758.html"
[6] "https://bj.ke.com/ershoufang/101114882758.html"
查看二手房的具体信息
采用上面相同的方法,获取该内容的节点位置:div.address
> web %>% html_nodes('div.address') %>% html_text()%>% str_remove_all("\\n") %>% str_remove_all(" ")
[1] "弘善家园高楼层(共27层)|2009年建|2室1厅|80.72平米|西北10人关注/2天前发布近地铁满五年VR看装修新上430万53,271元/平"
[2] "龙跃苑四区低楼层(共6层)|2005年建|2室1厅|90.41平米|南北7人关注/2天前发布满五年VR看装修新上535万59,175元/平"
[3] "北京方向低楼层(共19层)|2015年建|2室1厅|80.2平米|南西北1人关注/2天前发布近地铁满两年VR看装修新上随时看房569万70,948元/平"
[4] "磨房南里顶层(共18层)|1996年建|1室1厅|60.11平米|西南9人关注/2天前发布近地铁满两年VR看装修新上328万54,567元/平"
[5] "中关村东大院底层(共6层)|1992年建|2室1厅|57.2平米|东西0人关注/2天前发布近地铁满五年VR看装修新上820万143,357元/平"
[6] "丽景长安中楼层(共11层)|2013年建|3室2厅|124.42平米|南北8人关注/2天前发布满五年VR看装修新上585万47,019元/平"
说明:这里只显示前6条信息。由于所有的二手房信息用“|”字符连接在一起,所以需要将其拆分。
二手房:位置
采用上面相同的方法,获取该内容的节点位置:div.flood
> addr=web %>% html_nodes('div.flood') %>% html_text()%>% str_remove_all("\\n") %>% str_remove_all(" ")
> head(addr)
[1] "弘善家园" "龙跃苑四区" "北京方向" "磨房南里" "中关村东大院"
[6] "丽景长安"
二手房:价格
采用上面相同的方法,获取该内容的节点位置:div.priceInfo
> price=web %>% html_nodes('div.priceInfo') %>% html_text()%>% str_remove_all("\\n") %>% str_remove_all(" ")
> head(price)
[1] "430万53,271元/平" "535万59,175元/平" "569万70,948元/平" "328万54,567元/平"
[5] "820万143,357元/平" "585万47,019元/平"
由于价格数据包含了总价格和均价,所以需要将其拆分。
> price_list=strsplit(price,',')
> price_total=sapply(price_list, "[[", 1)
> head(price_total)
[1] "430万53" "535万59" "569万70" "328万54" "820万143" "585万47"
说明:总房价
> price_average=sapply(price_list, "[[", 2)
> price_average=as.numeric(gsub("元/平", "", price_average))
> head(price_average)
[1] 271 175 948 567 357 19
说明:均价,并且转换为数值型
二手房:房屋状况
采用上面相同的方法,获取该内容的节点位置:div.houseInfo
> houseInfo=web %>% html_nodes('div.houseInfo') %>% html_text()%>% str_remove_all("\\n") %>% str_remove_all(" ")
> head(houseInfo)
[1] "高楼层(共27层)|2009年建|2室1厅|80.72平米|西北"
[2] "低楼层(共6层)|2005年建|2室1厅|90.41平米|南北"
[3] "低楼层(共19层)|2015年建|2室1厅|80.2平米|南西北"
[4] "顶层(共18层)|1996年建|1室1厅|60.11平米|西南"
[5] "底层(共6层)|1992年建|2室1厅|57.2平米|东西"
[6] "中楼层(共11层)|2013年建|3室2厅|124.42平米|南北"
说明:由于房屋状况信息用“|”字符连接在一起,所以需要将其拆分。
楼层信息
> houseInfo_list=strsplit(houseInfo,"\\|")
> house_floor=sapply(houseInfo_list, "[[", 1)
> head(house_floor)
[1] "高楼层(共27层)" "低楼层(共6层)" "低楼层(共19层)" "顶层(共18层)" "底层(共6层)"
[6] "中楼层(共11层)"
房龄信息
> house_age=sapply(houseInfo_list, "[[", 2)
> house_age=as.numeric(gsub("年建", "", house_age))
> head(house_age)
[1] 2009 2005 2015 1996 1992 2013
户型信息
> house_type=sapply(houseInfo_list, "[[", 3)
> head(house_type)
[1] "2室1厅" "2室1厅" "2室1厅" "1室1厅" "2室1厅" "3室2厅"
面积信息
> house_area=sapply(houseInfo_list, "[[", 4)
> house_area=as.numeric(gsub("平米", "", house_area))
> head(house_area)
[1] 80.72 90.41 80.20 60.11 57.20 124.42
将爬取的信息整理成数据框类型
> houseData=data.frame(price_average,house_area,house_type,house_age,house_floor)
> head(houseData)
price_average house_area house_type house_age house_floor
1 271 80.72 2室1厅 2009 高楼层(共27层)
2 175 90.41 2室1厅 2005 低楼层(共6层)
3 948 80.20 2室1厅 2015 低楼层(共19层)
4 567 60.11 1室1厅 1996 顶层(共18层)
5 357 57.20 2室1厅 1992 底层(共6层)
6 19 124.42 3室2厅 2013 中楼层(共11层)
2.2 采用循环语句读取前多页的售房标题
从网页中可以看出,一共有100页的售房信息,我们这里只演示提取前10页的售房标题数据,爬取房屋信息数据的方法与之类似!
通过点击二手房下面的页面信息,可以发现每页的结尾是pg1,pg2,...。所以可以根据该规律构造多个页面并提取数据。
urlbase='https://bj.ke.com/ershoufang/pg'
paste(a,as.numeric(1),sep="")
title_list=NULL
for(i in 0:9){
url=paste(urlbase,as.numeric(i),seq="")
web=read_html(url,encoding = 'utf-8')
title=web %>% html_nodes('a.VIEWDATA.CLICKDATA.maidian-detail') %>% html_text() %>% str_remove_all("\\n") %>% str_remove_all(" ")
title=title[-which(title=="")]
title_list=c(title_list,title)
}
说明:该部分代码在脚本中编写并运行,注意第一页的url结尾是"pg0"。
> length(title_list)
[1] 300
> head(title_list)
[1] "东三环弘善家园高楼层两居室诚意出售"
[2] "龙跃苑四区2室1厅南北"
[3] "北京方向2室1厅南西北"
[4] "磨房南里西南一居带装修明厨明卫预约看房视野好"
[5] "中关村东大院经典两居室精装修随时看房"
[6] "丽景长安南北通透三居室高楼层精装修"
说明:运行循环语句脚本后,可以在控制台输入length(title_list)和head(title_list)获取titl_list的长度和前6条结果!