rvest爬虫及案例分析
2017-10-27 20:54
99 查看
由于最近准备着学习手数据挖掘,想着先从爬取数据开始。
现做一下总结,可能需要的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函数包更加健全。大家可以参考链接(值得收藏)
相关文章推荐
- 第二次作业:微信案例分析
- Linux Cluster案例分析之 Google的Linux集群解决方案
- 第二次作业,网易云音乐案例分析
- 第2次作业:软件案例分析
- 第二次作业:微信案例分析
- 【不错】oracle内存管理之PGA之案例分析:ora-04031与ora-04030错误分析与解决
- 架构设计案例分析-高速公路收费运营管理平台
- Java图形界面基础案例分析(满天星)
- Solr优化案例分析
- Hadoop学习笔记—20.网站日志分析项目案例(二)数据清洗
- 对"手机"的SEO案例分析
- WebService入门介绍及案例分析
- 案例分析:基于消息的分布式架构
- 银行业务调度系统案例分析
- unity shader案例分析(二)
- 如何获取(GET)一杯咖啡——星巴克REST案例分析
- 个人作业Week3-案例分析
- 一个Web报表项目的性能分析和优化实践(二):MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例
- 案例1:case when 案例分析
- 【转自Oracle官方技术博客】系统内存耗尽的案例分析