美文网首页生物信息学与算法数据科学与R语言程序员
R语言学习:使用rvest包抓取网页数据

R语言学习:使用rvest包抓取网页数据

作者: 无鱼二饼 | 来源:发表于2017-03-10 23:15 被阅读8651次

rvest是R语言一个用来做网页数据抓取的包,包的介绍就是“更容易地收割(抓取)网页”。其中html_nodes()函数查找标签的功能非常好用。以抓取天猫搜索结果页的宝贝数据为例说明rvest的使用。

分析网页

  1. 打开天猫,按F12键打开浏览器的开发工具。个人用的火狐,谁让Chrom不支持linux了,唉。不过还是chrome好用啊。其他浏览器都有类似的功能。
  2. 随便搜索个啥,比如核弹,我草还真出结果了!
  3. 接下来,在浏览器的开发工具"查看器"中查看网页的源码。或者按一下CTRL+SHIFT+C,选择任意宝贝。可以看到宝贝的图片、月销量等数据都是包含在<div class="product-iWrap">...</div>块中的。
  4. 打开该div块,哈哈,咱们需要的商品图片、链接、月销量、价格,以及商户名称等,都可以在里面找到了。话说,猫爹其实挺开放的,没有做太多限制,不然想抓这些数据就麻烦了。

接下来启动R,以下是用rvest包抓取宝贝数据的过程

  • 安装rvest包
install.packages("rvest")
  • 加载rvest包
library(rvest)
  • 保存搜索链接到对象gurl,链接的拼接方式挺有规律的
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"
  • 抓取数据保存到对象md中
  • %>%是管道操作符,意思是把左边的操作结果作为参数传递给右边的命令
  • div.product-iWrap 是CSS选择器的语法,即是 div class="div.product-iWarp"
md <- gurl %>% 
        read_html(encoding="GBK") %>% # 读取gurl的链接,指定编码为gbk
        html_nodes("div.product-iWrap")  # 筛选出所有包含在<div class="product-iWrap">...</div>块的内容
  • 从对象md继续筛选,获卖家名称等数据。
  • html_attr("data-nick") 是从html_nodes()筛选出的标签中,查找data-nick属性的值。
  • gsub()是字符串查找替换的函数,pattern是指定用来查找的正则表达式。
  • html_nodes("p.productTitle>a[title]"),”>"指定的筛选条件的父级标签。
  • html_text() 只抓取<标签>内容</标签>中的内容部分。
# 抓取卖家昵称和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="")
# 抓取宝贝名称等数据
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
# 最后保存成数据框对象并存盘备用,以及写入csv文件
options(stringsAsFactors = FALSE) # 设置字符串不自动识别为因子
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")

补充一个用rvest从赶集网抓取二手房单页面数据的代码

getData <- function(gurl){
# 抓取赶集网二手房源单页的数据
    library(rvest)
    # 赶集网首页筛选长沙-雨花区-砂子塘的二手房源,获得链接,o1为页数
    # 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")

    # 单个房源的puid
    puid <- tmp %>% html_attr("id")
    # 单个房源的链接
    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")
    # 标题
    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="")
    # 筛选朝向等数据
    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="")
    # 提取价格
    iPrice <- tmp %>% html_nodes("dl>dd>div.price>span:first-child") %>% html_text
    # 提取单价
    iTime <- tmp %>% html_nodes("dl>dd>div.time") %>% html_text %>% 
             gsub(pattern="[^0-9]",replacement="") %>% as.numeric
    # 合并数据框
    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)
    # 返回数据框
    return(iData)
}

相关文章

网友评论

  • 白马少年说:我复制您的代码尝试了一下,找到我自己的一个错误。price有了结果,但itemTitle是character(0)。同时我发现数量不一致,price是56个,而volume是54。有意思....仔细学习中
    白马少年说: @karen4tree 是的,使用了一些方法,也查看了源代码,还是没有搞定
    白马少年说: @囚徒训练日记 是的,使用了一些方法,也查看了源代码,还是没有搞定
    草木乾坤:你好,请问你解决了吗 Title 是设置不对 但是我改了之后也是对不齐。。无法保证一个品牌就一条描述。。。
  • 白马少年说:您好,我在尝试用您的代码进行抓取数据时:
    itemTitle<-md %>% html_nodes("p.productTitle>a[title]") %>%
    + html_attr("title")结果输出是0。
    price<-md %>% html_nodes("em[title]") %>%
    html_attr("data-item") %>%
    as.numeric
    输出的结果是55个NA.多次尝试调整代码,百思不得其解,望指导。非常感谢!

本文标题:R语言学习:使用rvest包抓取网页数据

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