美文网首页
R爬虫必备——rvest包的使用

R爬虫必备——rvest包的使用

作者: Clariom | 来源:发表于2020-07-28 15:56 被阅读0次

    上一期R爬虫必备——静态网页+动态网页简单介绍了网页的类型。在实际R爬虫过程中,针对不同的网页,采取的爬虫方法也会有所不同。通常情况下,R爬虫涉及的R包主要有3个:rvest、Rcurl和httr。

    1. rvest抓取静态网页数据****

    所谓静态网页,就是你打开一个目标网页,在网页里可以直接看到想要抓取的数据,点击鼠标右键查看源代码后发现在HTML结构中可以在本地找到刚刚在网页里的目标数据,这就是静态网页。对于这样的网页,rvest可以提供一套较为完整的数据抓取方案,配上一些小工具,就可以快速实现爬虫。

    1. Rcurl/httr包实现对网页动态加载数据的抓取

    对于网页动态加载的数据,继续使用rvest可能就不合适了。这时R提供了其他选择来实现相应的抓取目的。RCurl功能强大,但对初学者来说稍微有点难度。httr包相当于RCurl的精简版,相对轻巧易上手,功能虽不如RCurl那么齐全,但对于用户而言绝对友好。

    今天呢,主要从最简单的静态网页抓取R包——rvest开始,这款R包抓取静态网页的逻辑非常清楚,初学者可以很快理解和上手。下面简单看一下rvest数据抓取的几个核心函数:

    read_html():下载并解析网页
    html_nodes():定位并获取节点信息
    html_text():提取节点文本信息
    html_attr():提取节点属性信息
    

    rvest的这些函数如何使用呢?下面我们来简单看个案例——rvest包爬取链家网二手房信息,包括房子名字,房子具体信息(房型、面积、楼层等信息),房子地址,房子总价,房子每平方米单价等信息。

    image

    简单点,只为演示作用, 仅爬取第一页:http://hz.lianjia.com/ershoufang/pg1。具体代码如下:

    #加载所需的包:
    library("rvest")
    library("stringr")
    web <- read_html("http://hz.lianjia.com/ershoufang/pg1", encoding = "UTF-8")
    #提取房名信息:
    house_name <- web%>%html_nodes("div.info div.title a")%>%html_text()
    #提取房子详情链接:
    house_link <- web%>%html_nodes("div.info div.title a")%>%html_attrs("href")
    #提取房名基本信息并消除空格
    house_basic_inf <- web%>%html_nodes(".houseInfo")%>%html_text()
    house_basic_inf <- str_replace_all(house_basic_inf," ","")
    #提取二手房地址信息
    house_address <- web%>%html_nodes(".positionInfo a")%>%html_text()
    house_address <-house_address[seq(1,60,2)]
    #提取二手房总价信息
    house_totalprice <- web%>%html_nodes(".totalPrice")%>%html_text()
    #提取二手房单价信息
    house_unitprice <- web%>%html_nodes(".unitPrice span")%>%html_text()
    #创建数据框存储以上信息
    house<-data.frame(house_name,house_basic_inf,house_address,house_totalprice,house_unitprice)
    #将数据写入csv文档
    write.csv(house, file="../house.csv")
    

    整个代码的逻辑关系是这样:read_html()获取整个网页信息;html_nodes()用来定位到相应节点;html_text()用于获取节点的文本内容;html_attrs()用于获取节点的属性值信息。如:

    #read_html获取整个网页  
    web <- read_html("http://hz.lianjia.com/ershoufang/pg1", encoding = "UTF-8")
    #html_node获取包含房子名称的节点 
    tmp <- html_nodes(web,"div.info div.title a")
    #html_text获取该节点的文本信息
    house_name <- html_text(tmp)
    #html_attrs获取该节点的href属性信息
    house_link <- html_attr(tmp,"href")  
    

    为方便,信息的提取过程用“%>%”管道符加以连接,书写如下:

    web <- read_html("http://hz.lianjia.com/ershoufang/pg1", encoding = "UTF-8")
    house_name <- web%>%html_nodes("div.info div.title a")%>%html_text()
    house_link <- web%>%html_nodes("div.info div.title a")%>%html_attr("href")
    

    read_html()获取整个网页信息

    如:web <- read_html("http://hz.lianjia.com/ershoufang/pg1", encoding = "UTF-8"),返回的就是网页源码信息。

    web <- read_html("http://hz.lianjia.com/ershoufang/pg1", encoding = "UTF-8")
    web
    #{xml_document}
    #<html>
    #[1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n< ...
    #[2] <body>\n<script type="application/ld+json">{"@context": "https://ziyuan.baidu. ...
    
    • 在read_html()函数使用中,输入要爬取的网址以及编码格式,前者相信大家都没有问题,第二个网页的编码格式该如何判断呢?打开相应网页,然后右击,审查元素,打开网页源码,在源码中找到head标签,点开他,查找“Content Type”这样的字眼,在其后往往会带有“charset=xxxxxx”这样的描述。如下图,charset=utf-8,这表示该网页采用的是UTF-8的编码格式。
    image

    html_nodes()定位到相应节点

    如:tmp <- html_nodes(web, "div.info div.title a") ,返回值是"div.info div.title a"这个节点的信息,这个节点包含有房子的名字和详情链接信息。

    tmp <- html_nodes(web, "div.info div.title a")
    tmp
    # {xml_nodeset (30)}
    # [1] <a class="" href="https://hz.lianjia.com/ershoufang/103109543956.html" target ...
    # [2] <a class="" href="https://hz.lianjia.com/ershoufang/103109306746.html" target ...
    # [3] <a class="" href="https://hz.lianjia.com/ershoufang/103108174516.html" target ...
    # [4] <a class="" href="https://hz.lianjia.com/ershoufang/103109219801.html" target ...
    # [5] <a class="" href="https://hz.lianjia.com/ershoufang/103107527889.html" target ...
    # [6] <a class="" href="https://hz.lianjia.com/ershoufang/103109328178.html" target ...
    # [7] <a class="" href="https://hz.lianjia.com/ershoufang/103109405297.html" target ...
    # [8] <a class="" href="https://hz.lianjia.com/ershoufang/103109234723.html" target ...
    # [9] <a class="" href="https://hz.lianjia.com/ershoufang/103109496556.html" target ...
    # [10] <a class="" href="https://hz.lianjia.com/ershoufang/103109299194.html" target ...
    # [11] <a class="" href="https://hz.lianjia.com/ershoufang/103108655599.html" target ...
    # [12] <a class="" href="https://hz.lianjia.com/ershoufang/103108551516.html" target ...
    # [13] <a class="" href="https://hz.lianjia.com/ershoufang/103109485194.html" target ...
    # [14] <a class="" href="https://hz.lianjia.com/ershoufang/103108968651.html" target ...
    # [15] <a class="" href="https://hz.lianjia.com/ershoufang/103109357513.html" target ...
    # [16] <a class="" href="https://hz.lianjia.com/ershoufang/103109578551.html" target ...
    # [17] <a class="" href="https://hz.lianjia.com/ershoufang/103109454329.html" target ...
    # [18] <a class="" href="https://hz.lianjia.com/ershoufang/103108832328.html" target ...
    # [19] <a class="" href="https://hz.lianjia.com/ershoufang/103109578729.html" target ...
    # [20] <a class="" href="https://hz.lianjia.com/ershoufang/103109450043.html" target ...
    # ...
    
    • html_nodes()这步是关键,可以得到待抓取数据的节点信息。html_nodes这个函数的输入值:一个是read_html函数获取的整个网页信息web,另一个是定位节点表达式:可以是CSS选择器表达式,或者XPath表达式。我们这里"div.info div.title a"采用的CSS选择器表达式,那如何构建CSS选择器表达式呢?下一期会具体介绍。
    image

    html_text()获取节点的文本内容

    如:house_name <- html_text(tmp),获取节点下的文本信息,该文本信息就是房子的名称。

    house_name <- html_text(tmp)
    house_name
    # [1] "新出!景溪北苑,精装好房,看房 方便,"             
    # [2] "精装修三房,满五年且唯一,看房方便,房东诚售"      
    # [3] "滨江宝龙旁 精装修单身公寓 拎包入住 房东诚心出售"   
    # [4] "满两年自住精装  边套大客厅 房东诚心出售"           
    # [5] "房子满五年,精装修,边套,两房加开放式书房"        
    # [6] "视野开阔,采光好,适合居住,小区新,D铁近,教育好" 
    # [7] "此房视野开阔,一房朝南一房朝北,总价低,交通方便。"
    # [8] "临平山北 野风启城 房东诚心出售 中装修 价格实惠"    
    # [9] "满2年,自住精装修,看房方便,诚心卖"               
    # [10] "龙湖品质 地铁口 精装四房二卫  三阳台 诚心出售"     
    # [11] "小区位置好楼层采光好,视野开阔,自住装修。"        
    # [12] "国际城满两年刚需三房,双地铁,诚心卖可随时签约"    
    # [13] "投/资和过度首/选,小面积、低总价、地铁口"          
    # [14] "赞成林风标准三房,标准的3房2卫2阳台户型"           
    # [15] "采光好 房东诚心卖 小区环境户型好通透,一眼即中."   
    # [16] "荷塘极少户型, 本房满2,无增值税,户型方正,"      
    # [17] "融创品质 南北通透大阳台 中间楼层 诚心出售看房方便" 
    # [18] "中间楼层 南面无楼幢 视野好 阳光足 装修清爽"        
    # [19] "次新房、户型好、业主自住精装,随时看房,近地铁"    
    # [20] "此房房东自住精装,拎包入住,夹边套经典户型"        
    # [21] "税费少,总价低,刚需改善皆可。"                    
    # [22] "香樟名苑 三室二厅二卫一厨   有车库 价格面谈 带书房"
    # [23] "新出!房东诚心出售。价格可谈,看房随时"            
    # [24] "房子 精装修 满俩年 带露台 阿里巴巴"                
    # [25] "开发商精装修.未住人.户型通透.带小露台.拎包即住"    
    # [26] "交通方便,南北通畅,配套设施齐全!"                
    # [27] "此房视野开阔,一房朝南一房朝北,总价低,交通方便。"
    # [28] "梅堰小区 2室1厅 128万"                             
    # [29] "双地铁次新小区满二中间楼层.总共软装花了18万"       
    # [30] "精装小户型,满二年,朝阳,70年产权,成熟地段。" 
    
    • html_text()这步已经到了具体的信息抓取过程,但针对的是标签的文本内容。html_nodes这个函数的输入值:read_node函数获取的节点信息。连贯起来理解house_name <- web%>%html_nodes("div.info div.title a")%>%html_text(),就是先获取整个页面信息,然后定位到所需信息所在的节点,再在返回的节点中提取文本内容。
    image

    html_attr()获取节点的属性信息

    如:house_link <- html_attr(tmp,"href"),获取节点下的href这个属性值,该属性值就是房子的详情链接。

    house_link <- html_attrs(tmp,"href")
    house_link
    # [1] "https://hz.lianjia.com/ershoufang/103109543956.html"
    # [2] "https://hz.lianjia.com/ershoufang/103109306746.html"
    # [3] "https://hz.lianjia.com/ershoufang/103108174516.html"
    # [4] "https://hz.lianjia.com/ershoufang/103109219801.html"
    # [5] "https://hz.lianjia.com/ershoufang/103107527889.html"
    # [6] "https://hz.lianjia.com/ershoufang/103109328178.html"
    # [7] "https://hz.lianjia.com/ershoufang/103109405297.html"
    # [8] "https://hz.lianjia.com/ershoufang/103109234723.html"
    # [9] "https://hz.lianjia.com/ershoufang/103109496556.html"
    # [10] "https://hz.lianjia.com/ershoufang/103109299194.html"
    # [11] "https://hz.lianjia.com/ershoufang/103108655599.html"
    # [12] "https://hz.lianjia.com/ershoufang/103108551516.html"
    # [13] "https://hz.lianjia.com/ershoufang/103109485194.html"
    # [14] "https://hz.lianjia.com/ershoufang/103108968651.html"
    # [15] "https://hz.lianjia.com/ershoufang/103109357513.html"
    # [16] "https://hz.lianjia.com/ershoufang/103109578551.html"
    # [17] "https://hz.lianjia.com/ershoufang/103109454329.html"
    # [18] "https://hz.lianjia.com/ershoufang/103108832328.html"
    # [19] "https://hz.lianjia.com/ershoufang/103109578729.html"
    # [20] "https://hz.lianjia.com/ershoufang/103109450043.html"
    # [21] "https://hz.lianjia.com/ershoufang/103105364860.html"
    # [22] "https://hz.lianjia.com/ershoufang/103109300256.html"
    # [23] "https://hz.lianjia.com/ershoufang/103108452618.html"
    # [24] "https://hz.lianjia.com/ershoufang/103107750847.html"
    # [25] "https://hz.lianjia.com/ershoufang/103108517042.html"
    # [26] "https://hz.lianjia.com/ershoufang/103109088590.html"
    # [27] "https://hz.lianjia.com/ershoufang/103109554013.html"
    # [28] "https://hz.lianjia.com/ershoufang/103109603726.html"
    # [29] "https://hz.lianjia.com/ershoufang/103109415991.html"
    # [30] "https://hz.lianjia.com/ershoufang/103109101369.html"
    
    • html_attr()这步也是具体的信息抓取过程,但是针对属性进行提取。html_attr这个函数的输入值:一个是read_node函数获取的节点信息,另一个是属性标签(位于其实标签内)。连贯起来理解house_link <- web%>%html_nodes("div.info div.title a")%>%html_attr("href"),就是先获取整个页面信息,然后定位到所需信息所在的节点,再在返回的节点中提取href这个属性值。
    image

    以上就是rvest的基本用法,具体可以查看R包的说明文档。学会以上几个函数,基本上就可以抓取简单的静态网页了,其中稍有难度的就是html_node()函数中构建节点表达式:CSS选择器表达式XPath表达式,这部分内容在下一期做详细介绍!

    更多内容可关注公共号“YJY技能修炼”~~~

    往期回顾
    R爬虫在工作中的一点妙用
    R爬虫必备基础——HTML和CSS初识
    R爬虫必备基础——静态网页+动态网页

    相关文章

      网友评论

          本文标题:R爬虫必备——rvest包的使用

          本文链接:https://www.haomeiwen.com/subject/xxgfrktx.html