现在大家对爬虫的兴趣不断高涨,R和PYTHON是两个非常有力的爬虫工具。Python倾向于做大型爬虫,与R相比,语法相对复杂,因此Python爬虫的学习曲线会相对陡峭。对于那些时间宝贵,又想从网上获取数据的初学者而言,用R做爬虫是最好的选择,有三个原因:1、R语法相对直观,规则更加灵活;2、对于数据量不大的用户来数(小于百万级),R也能够非常自如地处理;3、先学习R爬虫,等熟悉爬虫的原理之后,在过渡到Python是很容易的。
这篇博文你会学到什么:
使用XML抓取表格数据(爬取勇士队球员数据)
使用rvest抓取网页数据(爬取关于特朗普的百度新闻)
使用jsonlite抓取json格式数据(爬取高德地图温州各个行政区域的中心)
使用RSelenium模拟登录抓取数据(模拟登录人大经济论坛爬取R语言板块数据)
使用PhantomJS不登陆抓取数据(抓取国家数据各省的近13个月CPI)
另外你也会学到一些数据处理的小技巧
表格数据是最容易抓取的数据格式,直接使用XML包中的readHTMLTable函数,一页中的多个表格会使用列表的形式存储,在使用readHTNLTable的时候,header=T可以标记出所抓取的表格是列名,大多说情况抓过来表格的列名是乱码的,你可以使用rvest::repair_encoding对它们进行修复。爬取勇士队球员数据的代码如下:
#抓取表格数据(抓取勇士队的球员数据)
library(XML)
url <- 'http://www.stat-nba.com/team/GSW.html'
dt1 <- readHTMLTable(url,header = T)
names(dt1[[1]]) <- rvest::repair_encoding(names(dt1[[1]]))
head(dt1[[1]])
球员 出场 首发 时间 投篮 命中 出手 三分 命中 出手 罚球 命中 出手 篮板
1 凯文-杜兰特 12 12 34.7 53.8% 8.9 16.6 46.7% 2.9 6.3 86.9% 4.4 5.1 7.5
2 斯蒂芬-库里 13 13 32.4 46.7% 7.5 16.2 38.8% 3.6 9.3 94.4% 6.5 6.8 4.7
3 克莱-汤普森 13 13 32.9 51.4% 8.5 16.5 47.1% 3.7 7.8 75.0% 0.5 0.6 3.8
4 德雷蒙德-格林 13 13 29.8 49.5% 3.5 7.0 35.7% 1.2 3.2 79.4% 2.1 2.6 7.9
5 大卫-韦斯特 12 0 11.3 68.6% 2.9 4.3 75.0% 0.3 0.3 80.0% 0.7 0.8 2.3
6 尼克-杨 12 0 13.0 44.1% 2.2 4.9 41.7% 1.7 4.0 60.0% 0.3 0.4 1.0
前场 后场 助攻 抢断 盖帽 失误 犯规 得分
1 0.8 6.8 4.9 0.6 2.4 3.4 2.3 25.2
2 0.5 4.2 6.7 1.8 0.2 2.6 2.2 25.2
3 0.5 3.4 2.7 0.7 0.8 1.8 2.2 21.1
4 1.1 6.8 6.7 1.0 1.3 3.2 3.0 10.2
5 1.0 1.3 1.3 0.7 1.4 1.4 1.6 6.8
6 0.3 0.8 0.9 0.8 0.1 0.4 1.1 6.3
rvest是R用户使用率最多的爬虫包,它简洁地语法可以解决大部分的爬虫问题。它的使用方法比较固定1、使用read_html读取网页;2、通过CSS或Xpath获取所需要的节点并使用html_nodres读取节点内容;3、结合stringr包对数据进行清理。下面使用它爬取关于特朗普的百度新闻,具体代码如下:
library(rvest)
library(stringr)
library(rlist)
url <- 'http://news.baidu.com/ns?cl=2&rn=20&tn=news&word=%E7%89%B9%E6%9C%97%E6%99%AE&ie=utf-8'
#抓取网页
httr_web <- read_html(url,encoding = 'utf-8')
#抓取新闻标题
title <- httr_web%>%html_nodes('h3>a')%>%html_text(trim = T)
#抓取新闻发布者与日期
author <- httr_web%>%html_nodes('p.c-author')%>%html_text(trim = T)
candidate_date=Sys.Date()%>%format('%Y年%m月%d日')
fun <- function(x){
re=if(length(x)==3){
re=c(x[1],candidate_date,x[length(x)])
}else{
re= x[-2]
}
re=data.frame(发布者=re[1],日期=re[2],时间=re[3])
return(re)
}
news_Trump <- data.frame(标题=title ,
author%>%str_split('\\s')%>%lapply(fun)%>%list.stack())
tail(news_Trump)
标题 发布者 日期 时间
15 特朗普访越车队驶过河内歌剧院 引众人围观 网易 2017年11月12日 6小时前
16 特朗普:美俄就政治解决叙利亚问题达成一致协议 环球网 2017年11月12日 9小时前
17 英媒:印度为迎接特朗普女儿 围捕乞丐暂住监狱 腾讯新闻 2017年11月12日 14小时前
18 【独家】他此行的外交礼遇有点不一样 环球网 2017年11月12日 7小时前
19 得分“A+”的不止有特朗普外孙女,更有这支军队 中国军网 2017年11月12日 6小时前
20 多位专家谈中美关系:两国合作前景广阔 中国新闻网 2017年11月12日 2小时前
json数据是一些列数据的嵌套,它的一般格式如下 {key1:var1:{key2:var2,...},...}, 这种格式的数据通常为网站的开放数据,可以申请目标网站的API,然后获取数据。获得API后,rvest可以很容易处理这种数据,但由于数据格式比较复杂,后期数据处理会有些繁琐。因此这里建议大家使用jsonlite中的fromJSON函数,它直接以嵌套列表的格式呈现数据,不建议大家使用RJSON中的fromJSON,它你会的到url多重自字符的错误。获取高德地图中温州各行政区域中心坐标的代码如下,你也可使用这个方法获取个行政区的json边界,方法类似,这里不再说明。
##抓取JSON数据(抓取温州各个行政区域的坐标)
library(jsonlite)
name='温州'
encoding_name <- iconv(enc2utf8(name),from='utf-8',to='ISO-8859-1',sub = "byte")%>%
str_replace_all('><','%')%>%str_sub(1,18)%>%str_to_upper()%>%
str_replace('<','%')
subdistrict_num=1
key_str='你的API'
url0 <- 'http://restapi.amap.com/v3/config/district?'
url <- paste0(url0,
'keywords=',encoding_name,'&',
'subdistrict=',subdistrict_num,'&',
'key=',key_str)
wz_center<- fromJSON(url)
wz_centers<-wz_center[['districts']][['districts']][[1]]
tail(wz_centers)
citycode adcode name center level districts
6 0577 330326 平阳县 120.565793,27.661918 district NULL
7 0577 330327 苍南县 120.427619,27.519773 district NULL
8 0577 330328 文成县 120.091498,27.786996 district NULL
9 0577 330329 泰顺县 119.717649,27.556884 district NULL
10 0577 330381 瑞安市 120.655148,27.778657 district NULL
11 0577 330382 乐清市 120.983906,28.113725 district NULL
使用RSelenium时,你首先要下载Selenium,chromedriver,直接百度,这里不再说明。下载之后要把Selenium放在你当前的工作目录,chromedriver放在chorm的目录下,win10用户Altt+x--cmd---'>'前面的即为工作目录,然后你还需要下载java,并把它放在你的环境变量中(注意区分用户环境还是系统环境),最后在命令窗口输入下面代码: java -jar selenium-server-standalone-3.4.0.jar 上面命令运行成功后我们就可已在R中使用RSelenium了,Selenium是一个模拟人点击网页的自动化测试模块,所有输入和点击的操作都可以用它实现。RSelenium的操作如下:
remoteDriver创建远程连接
open()打浏览器
navigate(url)打开网页
findElement、clickElement、sendKeysToElement三剑客进行一些列的选中、点击、输入操作
getElementAttribute("outerHTML")[[1]]转为HTML对象,然后使用rvest操作
library(RSelenium)
remDr <- remoteDriver(remoteServerAddr = "127.0.0.1" ,
port = 4444,
browserName = "chrome")
remDr$open() #打开浏览器
remDr$navigate('http://bbs.pinggu.org/forum-69-1.html')
step1 <- remDr$findElement(using = 'xpath',
"//*[@id='nv_forum']/div[6]/div[1]/div/div[4]/ul/li[3]/a")
step1$clickElement()
step21 <- remDr$findElement(using = 'xpath', '//*[@id="username"]')
step21$clickElement()
step21$sendKeysToElement(list(username ='用户名'))
step22 <- remDr$findElement(using = 'xpath', '//*[@id="password"]')
step22$clickElement()
step22$sendKeysToElement(list(password ='密码'))
step23 <- remDr$findElement(using = 'xpath', '/html/body/div[2]/div/div[2]/a')
step23$clickElement()
step3 <- remDr$findElement(using = "xpath","//*[@id='moderate']/table")
web <- step3$getElementAttribute("outerHTML")[[1]]%>%read_html()
dat3=data.frame(
标题=web%>%html_nodes('a.xst')%>%html_text(trim = T),
发布者=web%>%html_nodes('a.u')%>%html_text(trim = T),
发布时间=web%>%html_nodes('p>em>span')%>%html_text(trim = T),
最后回复者=web%>%html_nodes('p>em>a:nth-child(4)')%>%html_text(trim = T),
最后回复日期=web%>%html_nodes('p>em>a:nth-child(5)')%>%html_text(trim = T)
)
tail(dat3)
标题
75 R randomForest classification regression
76 求教R语言中的MSBVAR包出现的问题
77 【经典教材系列】Spatial and Spatio-temporal Bayesian Models with R - INLA
78 求助----关于R语言的randomforest包的一个问题
79 用R绘制水平方向的条形图并在相应位置添加标签
80 如何把散点和曲线花在一张图上
发布者 发布时间 最后回复者 最后回复日期
75 fengqifeng 2016-6-26 鱼铃五校名2 2017-11-10
76 xiaoqiang1789 2013-6-19 涅墨西斯随风 2017-11-10
77 wwqqer 2015-10-19 苦丁冰茶 2017-11-10
78 benbobo 2012-5-2 鱼铃五校名2 2017-11-10
79 慕目穆木 2017-11-9 nkunku 2017-11-10
80 awen1011 2017-11-2 GOD.M.W 2017-11-10
首先下载phantomjs,然后把下面代码块复制到text,保存后更改后缀名为.js,若需要抓取其他js网页,直接更改open中的内容即可。注意你的到的js文件要和phantomjs.exe放在相同的工作目录下。
// NDC.js
var webPage = require('webpage');
var page = webPage.create();
var fs = require('fs');
var path = 'NDC.html'
page.open('http://data.stats.gov.cn/easyquery.htm?cn=E0101', function (status) {
var content = page.content;
fs.write(path,content,'w')
phantom.exit();
});
运行system("./phantomjs NDC.js")后,会在你的工作目录下创建一个NDC.html文档,直接用read_html读就可以,然后获取所需的表格数据。
system("./phantomjs NDC.js")
web <- read_html("NDC.html")
dat4 <- (web%>%html_table())[[1]]
tail(dat4)
地区 2017年9月 2017年8月 2017年7月 2017年6月 2017年5月 2017年4月
26 西藏自治区 101.7 101.5 101.4 101.2 101.2 101.3
27 陕西省 102.2 102.7 102.1 102.0 101.8 101.1
28 甘肃省 102.1 101.8 101.4 101.3 100.8 100.4
29 青海省 102.3 102.3 101.6 101.6 101.0 99.8
30 宁夏回族自治区 101.4 101.6 101.3 101.7 101.8 101.3
31 新疆维吾尔自治区 102.8 101.9 101.7 102.1 102.1 101.5
2017年3月 2017年2月 2017年1月 2016年12月 2016年11月 2016年10月
26 102.0 102.4 102.8 103.0 102.9 102.7
27 100.0 99.7 101.5 101.2 101.5 101.5
28 100.2 100.3 101.7 101.4 101.2 101.1
29 100.1 100.5 102.0 101.9 102.0 102.1
30 100.7 100.3 102.6 102.5 102.3 102.4
31 101.2 101.5 102.8 102.3 102.4 101.9
欢迎大家关注微信公众号:数萃大数据
深度学习培训班【上海站】
时间:2017年12月23日
地点:上海创梦云实训创新中心
更多详情,请扫描下面二维码