加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

R语言之网络爬虫

(2017-08-04 14:35:40)
分类: R语言学习
该工具可以与谷歌浏览器结合使用,能够为复杂网站的元素生成CSS选择器,这款神器有助于我们快速找到html的节点信息。这篇文章主要介绍SelectorGadget的安装以及使用。

安装过程:①下载“SelectorGadget”(可直接在CSDN上搜索“SelectorGadget工具”即可看到上传的资源)

                 ②打开谷歌浏览器,在谷歌浏览器右上角,点击http://img.blog.csdn.net/20170807143557380,选择“更多工具”中的“扩展程序”,打开页面后,可直接将下载的SelectorGadget.crx拖拽到该页面即可。

                  ③完成后,会在谷歌浏览器页面右上角出现以下图标:http://img.blog.csdn.net/20170807143929387


使用过程:①打开某个网站,例如当当网的图书排行榜:“http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-1”

                     ②比如我们想获得书名的html节点信息,此时我们只需要先点击谷歌浏览器上图标http://img.blog.csdn.net/20170807143929387,然后再在书名的点击,如图一所示:

在图一中,我们发现很多地方都变成高亮(即黄色部分),但是我们只想获得书名信息,所以我们需要去除多余的信息,此刻只需在不需要的部分再次点击,即可去掉选中部分。例如,我们图一的基础上再点击图上上面的“往年”的“2013年”,即点击图二上的“2013”年

二、爬虫利器Rvest包(摘录自https://zhuanlan.zhihu.com/p/22940722?refer=rdatamining)
       rvest是R语言一个用来做网页数据抓取的包,包的介绍就是“更容易地收割(抓取)网页”。其中html_no
des()函数查找标签的功能非常好用。
相关的函数:
read_html():读取html文档;
html_nodes():获取指定名称的网页元素、节点;
html_text():获取指定名称的网页元素、节点文本;
html_attrs(): 提取所有属性名称及内容;
html_attr(): 提取指定属性名称及内容;
html_ tag():提取标签名称;
html_ table():解析网页数据表的数据到R的数据框中;
html_ session():利用cookie实现模拟登陆;
guess_encoding():返回文档的详细编码;
repair_encoding():用来修复html文档读入后乱码的问题。

 例子1:豆瓣图书 例:
 library(rvest)   #加载Rvest包
 web<-read_html("https://book.douban.com/top250?icn=index-book250-all",encoding="UTF-8") 
#用read_html函数读取网页信息(类似Rcurl里的getURL),在这个函数里只需写清楚网址和编码(一般 就是UTF-8)即可
  position<-web %>% html_nodes("p.pl") %>% html_text()
       #获取节点信息。用%>%符号进行层级划分,也是管道操作符,意思是把左边的操作结果作为参数传递给右边的命令。web就是之前存储网页信息的变量,所以我们从这里开始,然后html_nodes()函数获取网页里的相应节点。在下面代码里我简单的重现了原网页里的一个层级结构。可以看到,实际上我们要爬取的信息在25个class属性为pl的标签里的文本。
例子2:抓取广州番禺Q房网二手房信息
library(xml2)
library(rvest)
library(stringr)
basicURL <- "http://guangzhou.qfang.com/sale/fanyu"
WebSpider <- function(m){
  url <- str_c(basicURL,"/f",m)
  web <- read_html(basicURL,encoding = "UTF-8")
  name<- web %>% html_nodes(".showKeyword")%>%html_text() #获取小区名
  address <- web %>% html_nodes(".address~ span+ span") %>% html_text()#小区地址
  unitprice<- web %>% html_nodes(".show-price p") %>% html_text() #租金
  data.frame(name,unitprice,address)
}
results <- data.frame()
for(m in 1:14){ #78为小区信息的总页码 
  results <- rbind(results,WebSpider(m))#合并每一次循环输出的数据
  
}



 例子3:抓取广州番禺链家网二手房信息

library("xml2")
library("rvest")
library("stats")
library("base")
library("dplyr")
library("stringr")
#对爬取页数进行设定并创建数据框
i<-1:74
house_inf<-data.frame()
#使用for循环进行批量数据爬取(发现url的规律,写for循环语句)
for (i in 1:100){
  web<- read_html(str_c("https://gz.lianjia.com/ershoufang/panyu/pg",i),encoding="UTF-8")
  house_name<-web%>%html_nodes(".houseInfo a")%>%html_text()
  house_basic_inf<-web%>%html_nodes(".houseInfo")%>%html_text()
  house_basic_inf<-str_replace_all(house_basic_inf," ","")
  house_address<-web%>%html_nodes(".positionInfo a")%>%html_text()
  house_totalprice<-web%>%html_nodes(".totalPrice")%>%html_text()
  house_unitprice<-web%>%html_nodes(".unitPrice span")%>%html_text()
  #创建数据框存储以上信息
  house<-data_frame(house_name,house_basic_inf,house_address,house_totalprice,house_unitprice)
  house_inf<-rbind(house_inf,house)
  }

例子3:用R来爬取MDB上2016年最热门电影的一些特征。
library(xml2)
library(rvest)
library(stringr)
url <- 'http://www.imdb.com/search/title? count=100&release_date=2016,2016&title_type=feature&page=1&ref_=adv_prv'
webpage <- read_html(url,encoding = "UTF-8")
rank<- html_nodes(webpage,'.text-primary')%>%html_text() %>% as.numeric()#电影序列号
title<- html_nodes(webpage,'.lister-item-header a')%>%html_text()
description<- html_nodes(webpage,'.ratings-bar+ .text-muted')%>%html_text()
# 移除 '\n'
description<-gsub("\n","",description)
# 爬取runtime section
runtime<- html_nodes(webpage,'.text-muted .runtime')%>%html_text()
# 数据预处理: 去除“min”并把数字转换为数值型
runtime<- gsub(" min","",runtime)%>%as.numeric()
# 爬取genre
genre<- html_nodes(webpage,'.genre')%>%html_text()
# 去除“\n”
genre<-gsub("\n","",genre)
# 去除多余空格
genre<-gsub(" ","",genre)
# 每部电影只保留第一种类型
genre<-gsub(",.*","",genre)
# 转化为因子
genre<-as.factor(genre)
# 爬取IMDB rating
rating<- html_nodes(webpage,'.ratings-imdb-rating strong')%>%html_text()%>%as.numeric()
# 爬取votes section
votes<- html_nodes(webpage,'.sort-num_votes-visible span:nth-child(2)')%>%html_text()
# 移除“,”
votes<-gsub(",", "", votes)%>%as.numeric()
# 爬取directors section
directors<- html_nodes(webpage,'.text-muted+ p a:nth-child(1)')%>%html_text()
# 转为因子
directors<-as.factor(directors)
# 爬取actors section
actors<- html_nodes(webpage,'.lister-item-content .ghost+ a')%>%html_text()
# 转为因子
actors<-as.factor(actors)
# 爬取metascore section
metascore<- html_nodes(webpage,'.metascore')%>%html_text()
metascore<-gsub(" ","",metascore)
#meta score只有47个数据,可我们却爬取了50部电影。这个问题产生的原型是由3部电影没有Metascore数据。
#这是爬取所有网页都会遇到的常见问题,如果我们只是简单地用NA来填充这3个缺失值,它会自动填充第48到50部电影。
#通过一些可视化检查,我们发缺失matascore的是第33,42和48部电影。
for (i in c(33,42,48)){
  a <- metascore[1:(i-1)]
  b<-metascore[i:length(metascore)]
  metascore<- append(a, list("NA"))
  metascore<- append(metascore, b)
}
# 转换为数值型
metascore<- as.numeric(metascore)
summary(metascore)
#同样的问题也会发生在Gross变量上,我用同样的方式来解决
# 爬取revenue section
gross<- html_nodes(webpage,'.ghost~ .text-muted+ span')%>%html_text()
# 去除'$' 和 'M' 标记
gross<- gsub("M", "", gross)
gross<- substring(gross, 2, 6)
length(gross)
# 填充缺失值
for (i in c(2,29,33,42,48)){
  a <- gross[1:(i-1)]
  b <- gross[i:length(gross)]
  gross <- append(a, list("NA"))
  gross<- append(gross, b)
}
# 转为数值
gross<-as.numeric(gross)
#我们已经成功爬取了100部电影的11个特征,让我们创建一个数据框并看看结构。
movies_df <- data.frame(
  Rank = rank, 
  Title = title,
  Description = description, 
  Runtime = runtime,
  Genre = genre, 
  Rating = rating,
  Metascore = metascore, 
  Votes = votes,                           
  Gross_Earning_in_Mil = gross,
  Director = directors, 
  Actor = actors
)



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有