美文网首页R语言
R语言 | 网页数据爬取rvest包学习

R语言 | 网页数据爬取rvest包学习

作者: 一筐荚果 | 来源:发表于2017-09-01 15:30 被阅读294次

    从零开始学习rvest网络爬虫抓数据-Stone.Hou

    大神 Hadley rvest in GitHub
    参考資料
    rvest + CSS Selector 网页数据抓取的最佳选择-戴申
    R爬虫实战1(学习)—基于RVEST包

    rvest包简介

    rvest包是hadley大神的又一力作,使用它能更方便地提取网页上的信息,包括文本、数字、表格等,本文对rvest包的运用做一个详细介绍,希望能够帮助你在网页抓取的武器库中新添一把利器。

    rvest安装

    从CRAN上安装发行版:

    install.packages("rvest")
    

    也可以从github上安装开发版本:

    install.packages("devtools")
    devtools::install_github("hadley/rvest")
    

    rvest用法简介

    下面对rvest包中的主要函数的功能做一下说明:

    read_html() 读取html文档的函数,其输入可以是线上的url,也可以是本地的html文件,甚至是包含html的字符串也可以。

    html_nodes() 选择提取文档中制定元素的部分。可以使用css selectors,例如html_nodes(doc, "table td");也可以使用xpath selectors,例如html_nodes(doc, xpath = "//table//td")。本文后面的示例主要采用css selectors来提取html文档中我们想要的部分。

    html_tag() 提取标签名称;
    html_text() 提取标签内的文本;
    html_attr() 提取指定属性的内容;
    html_attrs() 提取所有的属性名称及其内容;
    html_table() 解析网页数据表的数据到R的数据框中。
    html_form(),set_values()和submit_form() 分别表示提取、修改和提交表单。

    在中文网页中我们经常会遇到乱码的问题,这里提供了两个函数来解决:guess_encoding()用来探测文档的编码,方便我们在读入html文档时设置正确的编码格式,repair_encoding()用来修复html文档读入后的乱码问题。

    还有一些函数,用来模拟网上的浏览行为,如html_session(),jump_to(),follow_link(),back(),forward(),submit_form()等等,这部分的工作还在进行中,相信rvest也会越来越强大。

    以上就是rvest包的主要功能函数,下面我们来尝试用rvest包中的函数抓取新赛季NBA常规赛首日的新浪NBA首页的新闻消息。

    rvest抓取示例1

    网页抓取的一般步骤我总结有如下三步:

    1. 首先,明确所要抓取的内容
    2. 然后,通过html的标签名称、属性以及id等确切的描述定位到该内容的位置
    3. 最后,提取相关的内容信息,必要时再做一些数据处理

    载入rvest包,读取新浪NBA官网网页

    library(rvest) # 载入rvest包
    library(stringr)
    library(XML)
    library(xml2)
    
    url='[http://sports.sina.com.cn/nba/'](http://sports.sina.com.cn/nba/') 
    web=read_html(url)
    

    抓取最新的NBA新闻消息列表

    html_nodes(web,".news-list-b a")%>%html_text
    #html_text()提取标签内的文本;
    # [1] "保罗仅13分快船出局"
    # [2] "数据展望马刺VS火箭"
    # ...
    # [32] "未战先奶!北境双枪改叫双头巨兽 骑士掌门略毒"
    # [33] "NBA正版授权页游 虚拟季后赛火热进行"
    # [34] "马刺火箭结果已出!小炮预测就是这么牛!"
    # [35] "APP"
    

    抓取NBA新闻热点

    html_nodes(web,".txt-a-hilight")%>%html_text
    ## [1] "卡哇伊35分阿杜27+10 马刺大胜勇士29分"
    ## [2] "詹皇三双骑士大胜尼克斯"
    ## [3] "升冠军旗詹皇含泪"
    ## [4] "利拉德39+9开拓者力克爵士"
    ## [5] "50大第1星:詹姆斯"
    ## [6] "詹皇联手甜瓜?"
    ## [7] "KD羡慕猛龙双枪友情:和威少之间未有过"
    

    抓取NBA新闻头条

    html_nodes(web,"#__liveLayoutContainer :nth-child(2) .txt-a-hilight")%>%html_text
    ## [1] "卡哇伊35分阿杜27+10 马刺大胜勇士29分"
    

    可以看到,如果想要准确的提取相关新闻消息,需要用css选择器准确地描述消息所处的位置,如.news-list-b a、.txt-a-hilight等。如果你熟悉css选择器,你将会很容易通过查看html的源代码来定位所要提取内容的位置。如果你不太熟悉,这个我们的大神也考虑到了,你可以直接使用一个基于JS的小工具来实现定位,插件的使用参见vignette("selectorgadget")。

    以上提取的主要是文本信息,对于网页中表格中的数据可以直接采用html_table()来获取,这部分示例详见微信公众号中案例数据的代码。一些复杂的模拟网上浏览行为的函数待rvest版本更新升级后我再做进一步的介绍。

    特别说明

    该示例结果为2016年10月26日下午5点运行得出,该演示代码及结果具有一定的时效性。

    示例2 读取简书中的一篇文章的标题-2017/5/1 by Stone.Hou

    library(rvest) # 载入rvest包
    library(stringr)
    library(XML)
    library(xml2)
    
    url='[http://www.jianshu.com/p/3cb5c6f2421c/'](http://www.jianshu.com/p/3cb5c6f2421c/') 
    web=read_html(url)
    h2title <- html_nodes(web,".show-content h2")%>%html_text
    for (i in 1:length(h2title)) {
    cat("这篇简书的第", i, "个标题的名称是:", h2title[i], "\n")
    }
    

    示例3 爬一下我爱豆五月天阿信的博文标题-安涵,IS girl

    library(rvest)
    library(stringr)
    library(XML)
    library(xml2)
    
    html <- read_html("[http://blog.sina.com.cn/s/articlelist_1265020392_0_1.html](http://blog.sina.com.cn/s/articlelist_1265020392_0_1.html)",encoding="UTF-8")
    
    title <- str_trim(
    html %>% html_nodes("span.atc_title") %>%
    html_text(),side='both')
    #str_trim过滤两边的空格
    
    for (i in 1:length(title)) {
    cat("五月天阿信的第", i, "个博文标题是:", title[i], "\n")
    }
    #五月天阿信的第 1 个博文标题是: 五月天.自傳 | Mayday.h…
    #五月天阿信的第 2 个博文标题是: 後來的我們
    #五月天阿信的第 3 个博文标题是: 勇敢
    #...
    

    rvest抓取示例--豆瓣图书Top250

    參考: 数据获取 爬虫利器Rvest包

    # 加载Rvest包
    library(rvest)
    library(stringr)
    library(XML)
    library(xml2)
    
    # 用read_html函数读取网页信息
    web<-read_html("[https://book.douban.com/top250?icn=index-book250-all](https://book.douban.com/top250?icn=index-book250-all)",encoding="UTF-8")
    position<-web %>% html_nodes("p.pl") %>% html_text()
    

    获取节点信息

    %>% 符号进行层级划分。web就是之前存储网页信息的变量,所以我们从这里开始,然后html_nodes()函数获取网页里的相应节点。在下面代码里我简单的重现了原网页里的一个层级结构。可以看到,实际上我们要爬取的信息在25个class属性为pl的<p>标签里的文本。

    # <p class=pl>
    # [清] 曹雪芹 著 / 人民文学出版社 / 1996-12 / 59.70元
    # </p>
    

    而对于这样的结构,在htmlnodes()函数里的写法就是简单的 "p.pl",其中“.”表示class属性的值,如果是id属性则用“#”,如果大家学过CSS选择器就很好理解了,是完全一致的。

    最后我们用html_text()函数表示获取文本信息,否则返回的是整个<p>标签。 总体上用以下一行代码就可以实现:

    position<-web %>% html_nodes("p.pl") %>% html_text()
    position
    

    想要学习更多,我们可以在Rstudio里的命令行输入如下代码查询html_nodes()函数的相关用法:

    ?html_nodes
    

    Rvest这个包的说明文档里给出了一些其他例子

    library(rvest)
    library(stringr)
    library(xml2)
    
    ateam <- read_html("[http://www.boxofficemojo.com/movies/?id=ateam.htm](http://www.boxofficemojo.com/movies/?id=ateam.htm)")
    
    # 然后下面代码分别获取了ateam这个网页里<center>标签里<td>的全部内容
    ateam %>% html_nodes("center") %>% html_nodes("td")
    # {xml_nodeset (7)}
    # [1] <td align="center" colspan="2"><font size="4">Domestic Tot ...
    # [2] <td valign="top">Distributor: <b><a href="/studio/chart/?s ...
    # [3] <td valign="top">Release Date: <b><nobr><a href="/schedule ...
    # [4] <td valign="top">Genre: <b>Action</b>\n</td>\n
    # [5] <td valign="top">Runtime: <b>1 hrs. 57 min.</b>\n</td>
    # [6] <td valign="top">MPAA Rating: <b>PG-13</b>\n</td>\n
    # [7] <td valign="top">Production Budget: <b>$110 million</b>\n< ...
    
    # 获取了ateam这个网页里<center>标签里<font>的全部内容
    ateam %>% html_nodes("center") %>% html_nodes("font")
    #[1] <font size="4">Domestic Total Gross: <b>$77,222,099</b></font>
    
    # 接着官方例子中还给出了获取特定序位的html标签的方法,用到了magrittr包里的extract2函数:
    library(magrittr)
    #下面两行代码都可以获得该网页中第一个<table>标签(由extract2(1)或`[[`(1)获取)中的所有<img>标签里的内容,
    ateam %>% html_nodes("table") %>% extract2(1) %>% html_nodes("img")
    ateam %>% html_nodes("table") %>% `[[`(1) %>% html_nodes("img")
    
    # 运行结果如下:
    # {xml_nodeset (6)}
    # [1] <img src="[https://images-na.ssl-images-amazon.com/images/M/MV5BMTc4ODc4NTQ1N15BMl5B](https://images-na.ssl-images-amazon.com/images/M/MV5BMTc4ODc4NTQ1N15BMl5B) ...
    # [2] <img src="[http://www.assoc-amazon.com/e/ir?t=boxofficemojo-20&amp](http://www.assoc-amazon.com/e/ir?t=boxofficemojo-20&amp);l=as2&o=1&amp ...
    # [3] <img src="[http://www.assoc-amazon.com/e/ir?t=boxofficemojo-20&amp](http://www.assoc-amazon.com/e/ir?t=boxofficemojo-20&amp);l=as2&o=1&amp ...
    # [4] ![](/img/misc/bom_logo1.png)
    # [5] ![](/img/misc/IMDbSm.png)
    # [6] ![]([http://b.scorecardresearch.com/p?c1=2&amp](http://b.scorecardresearch.com/p?c1=2&amp);c2=6034961&cv=2.0&cj=1)
    
    #同理我们也可以获得网页里前两个<table>标签储存的所有<img>标签里的内容:
    ateam %>% html_nodes("table") %>% `[`(1:2) %>% html_nodes("img")
    ateam %>% html_nodes("table") %>% extract(1:2) %>% html_nodes("img")
    

    rvest抓取豆瓣网电影数据例

    library(rvest)
    
    url = '[http://movie.douban.com/top250?format=text'](https://movie.douban.com/top250?format=text%27)
    web = html(url,encoding="UTF-8")
    
    score = html_text(web %>% html_nodes("span") %>% html_nodes("em"))
    
    year = web %>% html_nodes("p")
    year = html_text(year[seq(1,50,2)])
    
    gy = gregexpr('[0-9]{4}',year)
    gd = gregexpr("导演",year)
    gz = gregexpr("主演",year)
    
    time = sapply(1:length(gy),function(i) substr(year[i],gy[[i]],gy[[i]]+attr(gy[[i]],'match.length')-1))
    direct = sapply(1:length(gy),function(i) substr(year[i],gd[[i]] + 4,gz[[i]] - 4))
    actor = sapply(1:length(gy),function(i) substr(year[i],gz[[i]] + 4,gy[[i]] - 4))
    ga = gregexpr('\n',actor)
    actor = sapply(1:length(gy),function(i) substr(actor[i],1,ga[[i]] - 1))
    
    names = web %>% html_nodes("img") %>% html_attr("alt")
    names = iconv(names,"utf-8","gbk")
    
    rates = html_text(web %>% html_nodes("span"))
    rates = rates[grep("人评价",rates)]
    rates = gsub("人评价","",rates)
    
    movie = data.frame(电影 = names,时间 = time,得分 = score,评价人数 = rates,导演 = direct,主演 = actor)
    head(movie)
    

    用rvest包抓取宝贝数据

    library(rvest)
    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](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 <- 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/](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](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)
    }
    

    如何用rvest包爬取豆瓣图书250的数据-例2

    用R中的rvest包爬取豆瓣top250图书的基本信息(包括书名、评分、作者、译者、出版社、出版时间已经价格),然后根据出版社和出版时间进行进一步的分析

    #加载所需的包
    library("rvest");
    library("dplyr");
    library("stringr");
    
    #批量爬取豆瓣图书top250数据
    ind <-c(0,25,50,75,100,125,150,175,200,225)
    book_inf <-data.frame()
    
    #使用for循环进行批量数据爬取(发现url的规律,写for循环语句)
    for (i in1:length(ind)){
    web<-read_html(str_c("[https://book.douban.com/top250?start=](https://book.douban.com/top250?start=)",ind[i]),encoding="UTF-8")
    
    #爬取图书的作者、出版社、出版时间、价格
    p <-web%>%html_nodes("p.pl")%>%html_text()
    
    #爬取图书的name
    q <-web%>%html_nodes(".pl2 a")%>%html_text()
    
    #爬取图书的rate
    r <- web%>%html_nodes(".rating_nums")%>%html_text()
    
    #消除图书的name q中的空格
    q <-str_replace_all(q," ","")
    q <-str_replace_all(q,"\n","")
    
    #赋值图书书名和评分
    name <- q
    rate <- r
    
    #对p进行处理
    #提取作者名字
    p1 <-str_split_fixed(p,"/",2)
    author <- p1[,1];
    
    #提取翻译者名字
    p2 <-str_split_fixed(p1[,2],"/",2)
    a <-str_detect(p2[,1],"出版")
    b <- str_detect(p2[,1],"书店")
    interpre <-p2[,1]
    interpre[a|b] <-"NA"
    
    #提取出版商
    p3 <-str_split_fixed(p2[,2],"/",2)
    publisher <-p3[,1]
    publisher[a] <-p2[a,1]
    publisher[b] <-p2[b,1]
    
    #提取出版时间
    p4 <-str_split_fixed(p3[,2],"/",2)
    publish_time <-p4[,1]
    publish_time[a]<- p3[a,1]
    publish_time[b]<- p3[b,1]
    publish_time <- str_replace(publish_time,"年","-")
    publish_time <- str_replace(publish_time,"月","-")
    
    #提取价格
    p5 <-str_split_fixed(p4[,2],"/",2)
    price <- p5[,1]
    price[a] <-p4[a,1]
    price[b] <-p4[b,1]
    
    #创建数据框存储以上信息
    book <-data_frame(name,rate,author,interpre,publisher,publish_time,price)
    book_inf <-rbind(book_inf,book)
    }
    
    #对于少数不合规则的数据进行处理
    book_inf[52,5:7] <- book_inf[52,4:6]
    book_inf[52,4] <-"NA"
    book_inf[136,5:7]<- book_inf[136,4:6]
    book_inf[136,4]<- "NA"
    
    #根据出版社进行分析
    a <-summarise(group_by(book_inf,publisher),count = n())
    arrange(a,desc(count))
    # 根据图书出版的出版社进行分析,希望得到哪些出版社更容易出版好书
    由于出版社有80个,因此,此处只截取出版好书数量大于等于5本的出版社进行分析
    
    #根据出版时间进行分析
    b<-str_split_fixed(book_inf$publish_time,"-",2)
    b <- b[,1]
    table(b)
    # 根据图书出版时间进行分析,希望得到好书出版时间的规律:从图中可以看出,2007年出版的好书最多,且1997年至2011年,出版的好书都高于平均值(8本),除了2006年。
    

    爬取了戴申在科学网博客

    library(rvest)
    library(sqldf)
    library(gsubfn)
    library(proto)
    #creat a function
    extrafun <- function(i,non_pn_url){
    url <- paste0(non_pn_url,i)
    web <- html(url)
    papername<- web %>% html_nodes("dl.bbda dt.xs2 a") %>% html_text()%>% .[c(seq(2,20,2))] %>% as.character()
    paperlink<-gsub("\\?source\\=search","",web %>% html_nodes("dl.bbda dt.xs2 a") %>% html_attr("href"))%>% .[c(seq(2,20,2))]
    paperlink <- paste0("[http://blog.sciencenet.cn/](http://blog.sciencenet.cn/)",paperlink) %>% as.character()
    posttime <- web %>% html_nodes("dl.bbda dd span.xg1") %>% html_text() %>% as.Date()#这里取每篇文章的发布时间
    count_of_read <- web %>% html_nodes("dl.bbda dd.xg1 a") %>% html_text()
    count_of_read <- as.data.frame(count_of_read)
    count_of_read <- sqldf("select * from count_of_read where count_of_read like '%次阅读'")
    data.frame(papername,posttime,count_of_read,paperlink)
    }
    #crawl data
    final <- data.frame()
    url <- '[http://blog.sciencenet.cn/home.php?mod=space&uid=556556&do=blog&view=me&page='](http://blog.sciencenet.cn/home.php?mod=space&uid=556556&do=blog&view=me&page=%27)
    for(i in 1:40){
    extrafun(i,url)
    final <- rbind(final,extrafun(i,url))
    }
    dim(final)
    #[1] 400 4
    
    head(final)
    # papername
    # 1 此均值非彼均值
    # 2 [转载]孔丘、孔子、孔老二,它究竟是一只什么鸟?
    # 3 大数据分析之——k-means聚类中的坑
    # 4 大数据分析之——足彩数据趴取
    # 5 [转载]老王这次要摊事了,当年他主管的部门是事被重新抖出来。
    # 6 [转载]党卫军是这样抓人的。
    # posttime count_of_read
    # 1 2015-03-08 216 次阅读
    # 2 2015-02-10 190 次阅读
    # 3 2015-01-18 380 次阅读
    # 4 2015-01-10 437 次阅读
    # 5 2015-01-05 480 次阅读
    # 6 2015-01-05 398 次阅读
    # paperlink
    # 1 [http://blog.sciencenet.cn/blog-556556-872813.html](http://blog.sciencenet.cn/blog-556556-872813.html)
    # 2 [http://blog.sciencenet.cn/blog-556556-866932.html](http://blog.sciencenet.cn/blog-556556-866932.html)
    # 3 [http://blog.sciencenet.cn/blog-556556-860647.html](http://blog.sciencenet.cn/blog-556556-860647.html)
    # 4 [http://blog.sciencenet.cn/blog-556556-858171.html](http://blog.sciencenet.cn/blog-556556-858171.html)
    # 5 [http://blog.sciencenet.cn/blog-556556-856705.html](http://blog.sciencenet.cn/blog-556556-856705.html)
    # 6 [http://blog.sciencenet.cn/blog-556556-856640.html](http://blog.sciencenet.cn/blog-556556-856640.html)
    
    write.table(final,"final.csv",fileEncoding="GB2312")
    #抓取的数据需要在Excel进一步加工,加工后读取进来,进一步做分析
    a <- read.table("dai_shen_blog_0326.csv",header=TRUE,sep=";",fileEncoding="GB2312")#Mac OS 环境下,要sep=";"
    a$posttime <- as.Date(a$posttime)
    a$paperlink <- as.character(a$paperlink)
    a$papername <- as.character(a$papername)
    a$count_of_read_NO. <- as.numeric(a$count_of_read_NO.)
    library(ggplot2)
    qplot(posttime,count_of_read_NO.,data=a,geom="point",colour=repost,size=6)
    

    爬取了NBA 2014-2015常规赛技术统计排行 - 得分榜

    #Crawl NBA player statistics from sina
    #web [http://nba.sports.sina.com.cn/playerstats.php?s=0&e=49&key=1&t=1](http://nba.sports.sina.com.cn/playerstats.php?s=0&e=49&key=1&t=1)
    library(rvest)
    library(stringr)
    library(sqldf)
    rm(NBAdata)
    start <- seq(0,250,50)
    end <- seq(49,299,50)
    getdata <- function(i){
    url <- paste0('[http://nba.sports.sina.com.cn/playerstats.php?s=',start](http://nba.sports.sina.com.cn/playerstats.php?s=%27,start)[i],'&e=',end[i],'&key=1&t=1')
    rank <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(1)") %>% html_text()%>%.[-1]%>%as.numeric()
    player <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(2)") %>% html_text()%>%.[-1]%>%str_sub(9,100)%>%as.character()
    team <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(3)") %>% html_text()%>%.[-1]%>%str_sub(9,100)%>%as.character()
    avg_score <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(4)") %>% html_text()%>%.[-1]
    total_score <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(5)") %>% html_text()%>%.[-1]
    total_shoot <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(6)") %>% html_text()%>%.[-1]
    three_point <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(7)") %>% html_text()%>%.[-1]
    punish_point <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(8)") %>% html_text()%>%.[-1]
    avg_time <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(9)") %>% html_text()%>%.[-1]
    total_involve <- url %>% html_session() %>% html_nodes("table") %>% .[[2]] %>% html_nodes("td:nth-child(10)") %>% html_text()%>%.[-1]
    data.frame(rank,player,team,avg_score,total_score,total_shoot,three_point,punish_point,avg_time,total_involve)
    }
    NBAdata <- data.frame()
    for(i in 1:6){
    NBAdata <- rbind(NBAdata,getdata(i))
    }
    NBAdata <- sqldf("select distinct * from NBAdata")
    write.table(NBAdata,"NBAdata.csv",sep=",",fileEncoding="GB2312")
    
    head(NBAdata)
    # rank player team avg_score total_score
    # 1 1 拉塞尔-威斯布鲁克 雷霆 27.3 1556
    # 2 2 詹姆斯-哈登 火箭 27.1 1900
    # 3 3 勒布朗-詹姆斯 骑士 25.8 1600
    # 4 4 安东尼-戴维斯 鹈鹕 24.6 1403
    # 5 5 德马库斯-考辛斯 国王 23.8 1308
    # 6 6 斯蒂芬-库里 勇士 23.4 1618
    # total_shoot three_point punish_point avg_time
    # 1 42.7% 30.1% 84.6% 33.8
    # 2 44% 36.8% 86.6% 36.8
    # 3 49.2% 35.4% 71.9% 36.2
    # 4 54.5% 10% 81.4% 36.2
    # 5 46.5% 28.6% 80.2% 33.7
    # 6 47.9% 42.2% 91.4% 32.9
    # total_involve
    # 1 57
    # 2 70
    # 3 62
    # 4 57
    # 5 55
    # 6 69
    
    

    拉勾网爬了一下,例子

    library(rvest)
    lagou <- "[http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc](http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc)
    =&workAddress=&city=%E6%B7%B1%E5%9C%B3&requestId=&pn=3"
    web<-html(lagou,encoding="UTF-8") #读取数据,规定编码
    #之前我是用关键字搜索,阅读html代码,获得html_nodes里需要什么属性,不过许多浏览器有开发者工具,可以直接获得层级信息。如遨游
    position<-web %>% html_nodes("li div.hot_pos_l a") %>% html_text()
    #上面就是直接读取数据,获得位置信息
    #不过在后面做其他网站时发现,有时候信息储存在同类数据里(如div没有class等等),建议是找一个大的分类,先获得表格信息,再做数据
    list_lagou<-web %>% html_nodes("li.clearfix")
    #这里正确找准正确的划分点很重要。有<li class="odd clearfix">,其实用li.clearfix一样可以取(对于空格二选一,如"li.odd"或者"li.clearfix")
    #接下来的company/position照选即可,因为事先已经分好了list,所以每一个出多少心里有数。。
    
    

    在讲完原理之后,现在开始尝试写代码,因为里面涉及太多的选取数据工作。为了避免出现太多变量,我最后是编了一个函数,输出数据库。

    #下面开始写代码,首先写一个函数getdata,会输出一个数据框
    getdata<-function(page,urlwithoutpage){
    url=paste0(urlwithoutpage,page) #这里输入拉勾网没有页码的url
    web<-html(url,encoding="UTF-8") #读取数据,规定编码,access用
    list_lagou<-web %>% html_nodes("li.clearfix") #获得一个清单,15个职位
    title<-list_lagou %>% html_nodes("div.hot_pos_l div.mb10 a")%>%html_text()
    company<-list_lagou %>% html_nodes("div.hot_pos_r div.mb10 a")%>%html_text()
    link<-gsub("\\?source\\=search","",list_lagou %>% html_nodes("div.hot_pos_l div.mb10 a")%>%html_attr("href"))
    #接下来的由于数据都存在span里,没有很好的划分。这个取数要复杂一些。我在这里,研究他们的表,先取15个完整list,然后用seq等序列取数
    #之后要研究是否有更好的方法
    #如果有table,可以直接用data.table取数更快。。。
    temp<-list_lagou %>% html_nodes("div.hot_pos_l span")
    city<-temp[seq(1,90,by=6)] %>% html_text()
    salary<-gsub("月薪:","",temp[seq(2,90,by=6)]%>% html_text())
    year<-gsub("经验:","",temp[seq(3,90,by=6)]%>% html_text())
    degree<-gsub("最低学历:","",temp[seq(4,90,by=6)]%>%html_text())
    benefit<-gsub("职位诱惑:","",temp[seq(5,90,by=6)]%>% html_text())
    time<-temp[seq(6,90,by=6)]%>%html_text()
    data.frame(title,company,city,salary,year,degree,benefit,time,link)
    }
    

    获取函数,这里先爬一页!

    url<-"[http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc=&workAddress=&city=%E6%B7%B1%E5%9C%B3&requestId=&pn=](http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc=&workAddress=&city=%E6%B7%B1%E5%9C%B3&requestId=&pn=)"
    final<-data.frame()
    for (i in 3){
    final<-rbind(final,getdata(i,url))
    } #定义个数,把上面的getdata得到的Data.frame合并
    
    head(final)
    

    R的爬虫和回归模型案例-以北京自如房租价格为例

    library(rvest)
    library(stringr)
    library(XML)
    library(xml2)
    
    WebSpider <- function(m){
    url <- str_c(cp,"?p=",m)
    web <- read_html(url,encoding = "UTF-8")#抓取网页信息
    name_rough <- web %>% html_nodes("h3") %>% html_text() #获取粗房屋名
    area_rough <- web %>% html_nodes("h4") %>% html_text() #提取区位
    price_rough <- web %>% html_nodes("p.price") %>% html_text() #提取价格
    price <- str_extract(price_rough, "[0-9]+") %>% as.numeric()#提取精确价格
    detail <- web %>% html_nodes("div.detail") %>% html_text() #提取其他信息
    
    #合并成数据框
    data.frame(name_rough,area_rough,forward,mate_num,location,price,detail)
    
    # 4、接着是观察翻页规律,然后遇到了一个坑。原以为之后的页码不过是[http://www.ziroom.com/z/nl/z3.html](http://www.ziroom.com/z/nl/z3.html)的基础上加上/1、/2........,我依照这个思路抓了一番,也获得了将近4000多条数据,原以为这大概就是全部吧。但我仔细看数据才发现,这样下来的基本都是房山、大兴和通州等的数据,基本没有城六区的,城六区的只有选了区域选项后才会出现:
    dc <- "[http://www.ziroom.com/z/nl/z3-d23008614.html](http://www.ziroom.com/z/nl/z3-d23008614.html)"
    xc <- "[http://www.ziroom.com/z/nl/z3-d23008626.html](http://www.ziroom.com/z/nl/z3-d23008626.html)"
    cy <- "[http://www.ziroom.com/z/nl/z3-d23008613.html](http://www.ziroom.com/z/nl/z3-d23008613.html)"
    hd <- "[http://www.ziroom.com/z/nl/z3-d23008618.html](http://www.ziroom.com/z/nl/z3-d23008618.html)"
    ft <- "[http://www.ziroom.com/z/nl/z3-d23008617.html](http://www.ziroom.com/z/nl/z3-d23008617.html)"
    sjs <- "[http://www.ziroom.com/z/nl/z3-d23008623.html](http://www.ziroom.com/z/nl/z3-d23008623.html)"
    cp <- "[http://www.ziroom.com/z/nl/z3-d23008611.html](http://www.ziroom.com/z/nl/z3-d23008611.html)"
    
    # 这样一来,只有逐区的来进行翻页爬了。为此,只能选定部分区域来做分析了。
    results_cp <- data.frame()
    for(m in 1:118){ #118为昌平区信息的总页码
    results_cp <- rbind(results_cp,WebSpider(m))#合并单个区每一次循环输出的数据
    }
    #依次重复获得7个区的数据
    results <- rbind(results_cp, results_cy,results_dc,results_ft,
    results_hd,results_sjs,results_xc) #将所有各区数据的合并
    
    }
    
    

    相关文章

      网友评论

        本文标题:R语言 | 网页数据爬取rvest包学习

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