R语言网络数据爬取

现在大家对爬虫的兴趣不断高涨,R和PYTHON是两个非常有力的爬虫工具。Python倾向于做大型爬虫,与R相比,语法相对复杂,因此Python爬虫的学习曲线会相对陡峭。对于那些时间宝贵,又想从网上获取数据的初学者而言,用R做爬虫是最好的选择,有三个原因:R语法相对直观,规则更加灵活;对于数据量不大的用户来数(小于百万级),R也能够非常自如地处理;先学习R爬虫,等熟悉爬虫的原理之后,在过渡到Python是很容易的。R中有好几个包都可以抓取网页数据,但是rvest + CSS Selector最方便。

一、rvest包简介与安装

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

1.rvest包的安装与加载

install.packages("rvest")
library(rvest)

2.rvest包的函数

函数 作用
read_html() 读取 html 页面
html_nodes() 提取所有符合条件的节点
html_node() 返回一个变量长度相等的list,相当于对html_nodes()取[[1]]操作
html_table() 获取 table 标签中的表格,默认参数trim=T,设置header=T可以包含表头,返回数据框
html_text() 提取标签包含的文本,令参数trim=T,可以去除首尾的空格
html_attrs(nodes) 提取指定节点所有属性及其对应的属性值,返回list
html_attr(nodes,attr) 提取节点某个属性的属性值
html_children() 提取某个节点的孩子节点
html_session() 创建会话

二、rvest包应用示例

1. 网页标题的爬取

新浪NBA

R语言代码
library(pacman)
p_load(xml2,rvest,dplyr,stringr,tidyverse) 
urlb <- "http://sports.sina.com.cn/nba/"
web<-read_html(urlb) 
title<-web %>% html_nodes(".item p a") %>% html_text()
爬取结果
 title
 [1] "利拉德挖墙角?点赞联手艾顿言论组冲冠新搭档"
 [2] "保罗:我不会在明天退役 有伤在身但不想多谈" 
 [3] "连续两场大胜共赢60分 东契奇:根本停不下来" 
 [4] "基德讽刺看不起他们的人 没错,是一场大屠杀" 
 [5] "艾顿不满被雪藏和主帅爆发冲突 续约前景黯淡" 
 [6] "保罗正负值-39创生涯纪录 太阳还有比他更糟的"

2. 网页表格的爬取

上海证券交易所_上证综合指数成分股列表 (sse.com.cn)

R语言代码
library(pacman)
p_load(XML,rvest,dplyr,stringr,tidyverse) 
urlb <- "http://www.sse.com.cn/market/sseindex/indexlist/s/i000001/const_list.shtml"
#xpath <- '//*[@id="content_ab"]/div[1]/table'
nodes <- html_nodes(read_html(urlb), ".tablestyle")
#nodes<- html_nodes(read_html(urlb), xpath=xpath)
tables <- html_table(nodes)    
restab <- tables[[1]]
head(restab)
爬取结果
  <chr>                              <chr>                              <chr> 
1 "浦发银行\r\n            (600000)" "白云机场\r\n            (600004)" "东风~
2 "中国国贸\r\n            (600007)" "首创环保\r\n            (600008)" "上海~
3 "包钢股份\r\n            (600010)" "华能国际\r\n            (600011)" "皖通~
4 "华夏银行\r\n            (600015)" "民生银行\r\n            (600016)" "日照~
5 "上港集团\r\n            (600018)" "宝钢股份\r\n            (600019)" "中原~
6 "上海电力\r\n            (600021)" "山东钢铁\r\n            (600022)" "浙能~
爬取结果整理
library(tidyverse)
pat1 <- "^(.*?)\\((.*?)\\)"
tab1 <- restab %>%
  ## 将三列合并为一列,结果为字符型向量
  reduce(c) %>%
  ## 去掉空格和换行符,结果为字符型向量
  stringr::str_replace_all("[[:space:]]", "") %>%
  ## 提取公司简称和代码到一个矩阵行,结果为字符型矩阵
  stringr::str_match(pat1)
tab <- tibble(
  name = tab1[,2],
  code = tab1[,3])
head(tab)
  name     code  
  <chr>    <chr> 
1 浦发银行 600000
2 中国国贸 600007
3 包钢股份 600010
4 华夏银行 600015
5 上港集团 600018
6 上海电力 600021

3. 网页连接的爬取

澎湃精选

R语言代码
library(rvest)
library(stringr)
url <-"https://thepaper.cn/"
web <- read_html(url)    #读取html网页的函数
news <- web %>% html_nodes('h2 a')
title <- news %>% html_text()  #获取其中的文字部分
link <- news %>% html_attrs()  #获取每个标题对应的网址

link1 <- c(1:length(link))
for(i in 1:length(link1))
{
  link1[i]<- link[[i]][1]
}
link2 <- paste("https://www.thepaper.cn/",link1,sep="")
爬取结果
link2
 [1] "https://www.thepaper.cn/newsDetail_forward_18113579"
 [2] "https://www.thepaper.cn/newsDetail_forward_18111927"
 [3] "https://www.thepaper.cn/newsDetail_forward_18112840"
 [4] "https://www.thepaper.cn/newsDetail_forward_18112721"
 [5] "https://www.thepaper.cn/newsDetail_forward_18113483"
 [6] "https://www.thepaper.cn/newsDetail_forward_18113503"
 [7] "https://www.thepaper.cn/newsDetail_forward_18113375"
 [8] "https://www.thepaper.cn/newsDetail_forward_18113493"
爬取整体结果
library(rvest)
library(stringr)
url <-"https://www.thepaper.cn/"

web <- read_html(url)    #读取html网页的函数
news <- web %>% html_nodes('h2 a')
title <- news %>% html_text()  #获取其中的文字部分
link <- news %>% html_attrs()  #获取每个标题对应的网址
link1 <- c(1:length(link))
for(i in 1:length(link1))
{
  link1[i]<- link[[i]][1]
}
link2 <- paste("https://www.thepaper.cn/",link1,sep="")

##获得每条新闻的全文
news_content<-c(1:length(link2))
for(i in 1:length(link2))
{
  web1 <- read_html(link2[i])
  {
    if(length(html_nodes(web1,'div.news_txt'))==1)
      news_content[i]<- html_text(html_nodes(web1,'div.news_txt'))
    else
      news_content[i]<- trimws(str_replace_all((html_text(html_nodes(web1,'div.video_txt_l p'))), "[\r\n]" , ""))
  }
} 

##获得每条新闻的时间
news_date <- c(1:length(link2))
for(i in 1:length(link2))
{
  web1 <- read_html(link2[i])
  {
    if(length(html_nodes(web1,'div.news_txt'))==1)
      news_date[i]<- trimws(str_replace_all((html_text((html_nodes(web1, "div p"))[2])), "[\r\n]" , ""))
    else
      news_date[i]<- trimws(str_replace_all((html_text(html_nodes(web1,'div.video_txt_l span'))), "[\r\n]" , ""))
  }
} 

date <- c(1:length(link2))
time <- c(1:length(link2))
for(i in 1:length(link2))
{
  date[i] <- substring(news_date[i],1,10)
  time[i] <- substring(news_date[i],12,16)   # is.character(news_date[i])
}

news_01 <- data.frame(title,date,time,url=link2,news_content)
write.csv(news_01,file=" news_information.csv")

爬取结果展示

总结

rvest的确是一个很好地数据抓取工具,不过他的强项更多在于网页解析,你可能惊艳于rvest强大的解析能力,有两套解析语法可选(Xpath、css),短短几个关键词路径就可以提取出来很重要的数据。网络爬虫是讲呈现在网页上以非结构格式(html)存储的数据转化为结构化数据的技术,该技术非常简单易用。rvest是R用户使用率最多的爬虫包,它简洁的语法可以解决大部分的爬虫问题。

参考文献

1.(R语言 网站数据获取 (rvest)——网络爬虫初学)[https://www.cnblogs.com/adam012019/p/14862610.html]
2.(R语言简单动态网页爬虫(rvest包)示例)[https://blog.csdn.net/seeyouer1205/article/details/117218645]

posted @ 2022-05-16 17:25  郝hai  阅读(2256)  评论(0编辑  收藏  举报