rvest爬虫及案例分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40584718/article/details/78369021

由于最近准备着学习手数据挖掘,想着先从爬取数据开始。


现做一下总结,可能需要的R包有: rvest(主要)、xml2、stringr(主要用来实现字符串处理)

一、简单介绍rvest函数

read_html() #用来下载网页
htnl_nodes() #用来标记要抓取网页元素的节点
html_attrs() #用来下在相应的网址(2,3函数单数情况也可以使用)
html_tag() #提取标签名称
html_table() #用来抓取表格

注:1.html_table()在网页结构比较简单的情况下比较实用链接(这个案例就可以通过html_table()轻松抓取,可以自己动手试一试)

二.以下以具体的例子来解释

1.抓取慕课网所有的课程信息

在网易云课堂看了R实战,老师演示了这个实例感觉实现的效果不好,所以自己尝试了一下

思路

- 先抓取7个大类课程的网址

- 然后抓取每一类具体的文本信息

- 用循环来实现7大类

1.1问题:

主要在: 翻页的实现

刚开始就看了三个类,随便翻了一下以为每一类的页码都是10页,然而并不是,最后几类每一个只有几页,所以要先解决每一类有几页的问题,通过观察发现,如果每一类如果个数超过一页,它就会出现翻页栏,我们可以定位到那,然后通过字符串处理来提取出总的页码数

但是这个例子还有一个例外,你会发现第七大类,它没有翻页,没有翻页栏,这尴尬了,生活中不是缺少美,是缺少发现美的眼睛。所以观察每一类的每一页会发现,当前页面的案例个数可能为22,或23,所以这是一个关键,可以用此来判定是否发生了翻页效果。

总的代码如下:

library(rvest)
library(stringr)
#先提取7大类网址
URL<-http://www.imooc.com # 慕课网网址
web<-read_html(URL,encoding="utf-8")
site<-web%>%html_nodes('div.itema')%>%html_attrs()
for(i in1:(length(site))){
ifelse(i==length(site),site[i]<-site[[i]][2],site[i]<-site[[i]][1])
WEB<-paste0(URL,site)}
#用WEB来储存七大类网址信息
DAT<-data.frame()#建立空的数据框,然后用rbind来封装数据(比较常用)
for(j in1:length(WEB)){
url<-WEB[j]
web<-read_html(url)
course1<-web%>%html_nodes("div.course-card-contenth3")%>%html_text()
#判断每一页案列数目,判定是否需要翻页
if(length(course1)>=22)
{page<-web%>%html_nodes('div.course-list div.page a')%>%html_attrs()
#字符串处理提取页码,其中y就是页码数(需要as.numeric()处理)
x<-page[[length(page)]][1]
x<-str_split_fixed(x,"page=",2)
y<-x[,2]
y<-as.numeric(y)
dat<-data.frame()
for(i in 1:y){
url1<-"&page="
#连接形成每一页的网址
#网址大的连接
web2<-paste0(url,url1,i)
Site<-read_html(web2)
#提取每一页的文本信息
course<-Site%>%html_nodes("div.course-card-contenth3")%>%html_text()
text<-Site%>%html_nodes("div.course-card-infospan")%>%html_text()
rank<-text[seq(1,length(text),2)]
num<-text[seq(2,length(text),2)]
note1<-Site%>%html_nodes("div.clearfixp")%>%html_text()
note<-note1[-c(1,length(note1))]
#data装入数据框
data<-data.frame(course,rank,num,note)
#将循环的数据封装
dat<-rbind(dat,data)} }
else{
Site<-read_html(url)
#提取每一页的文本信息
course<-Site%>%html_nodes("div.course-card-contenth3")%>%html_text()
text<-Site%>%html_nodes("div.course-card-infospan")%>%html_text()
rank<-text[seq(1,length(text),2)]
num<-text[seq(2,length(text),2)]
note1<-Site%>%html_nodes("div.clearfixp")%>%html_text()
note<-note1[-c(1,length(note1))]
#data装入数据框
dat<-data.frame()
data<-data.frame(course,rank,num,note)
#将循环的数据封装
dat<-rbind(dat,data)
dat
}
DAT<-rbind(DAT,dat)}
#设置最大输出行数
options("max.print"=10000)
print(DAT)
#保存文件
write.csv(DAT,file="DAT.csv")

1.2优化方向:

可以构造封装函数,通过递归实现,代码明显的感觉就是有冗余,但是就目前个人R语言方面的知识,这还是短板,代码还可以进一步该进。

2.关于天气的抓取,要点在编码方式的转变,代码如下:

ind<-c(seq(201601,201612,1),seq(201701,201712,1))
weather_info<-data.frame()
library(rvest)
library(stringr)
for(i in1:length(ind)){
site1<-"http://www.tianqihoubao.com/aqi/chengdu-"
site2<-".html"
web<-read_html(str_c(site1,ind[i],site2),encoding="gb2312")
qq<-web%>%html_nodes("td")%>%html_text()
M<-matrix(qq,nrow=10)
P<-t(M)
P<-iconv(P,"utf-8","gbk")
P<-gsub("^\\s+|\\s+$","",P)
#正则表达式^表示开始位置,$表示末尾,+表示至少一次
P<-P[-1,]
#P<-as.data.frame(P)
weather_info<-rbind(weather_info,P)
}
weather_info
names(weather_info)<-c("日期","质量等级","AQI指数","当天AQI排名","PM2.5","PM10","So2","No2","Co","O3")#恢复表头
注:
- 1.注意两个函数的用法
iconv(x,from=””,to=””,sub=NA)
gsub(pattern,replacement,x,ignore.case=FALSE,fixed=FALSE)
- 2.就是使用read_html()要注意网页的编码格式,一般存放在head()结构中,主要有uft-8,gbk,gb2312等。他们之间的区别可以参考链接
- 3.问题二2,二.3主要用到的是stringr包,但是大多数字符串处理还是可以通过base包中的函数来实现,stringr函数包更加健全。大家可以参考链接(值得收藏)

猜你喜欢

转载自blog.csdn.net/qq_40584718/article/details/78369021
今日推荐