之前的一系列文章都讲了关于python的基础知识,接下来的一些内容会讲一讲可视化方面的内容。对于可视化而言,Python和R语言,我还是非常喜欢使用R语言的,因为用她作图既简介又高效。今天我们就分享一篇关于使用R语言抓取上海近7年天气数据案例。
先来看看,我们需要抓取的网站内容,如图所示:
红框中就是我们需要抓取的上海天气信息,包含日期、最高气温、最低气温、天气、风向和风力。而这些内容是可以在网页的源代码中查询得到,你可以按一下键盘中的F12快捷键,我以自己的Chrome浏览器为例,可以返回如下图所示的信息:
通过点击红框中的按钮,再回到左侧或上侧的原始网页,任意点击日期值或其他指标值,就会立刻返回如下图所示的内容:
发现没有,网页中8.1日的天气数据全都包含在ul这个标签内,而这个标签的父级标签是红框中的div标签。只要锁定这两个标签,就可以快速的将网页中天气数据抓下来。
知道如何从源代码中查询网页数据所在的标签,接下来只需要借助R语言的rvest包,就可以轻松抓数啦。关于该包,我先只介绍如下三个重要的函数:
html_session(url, ...)
读取并下载url源代码
html_nodes(x, css, xpath)
运用css标签抓取信息
html_text(x, trim = FALSE)
抓取的内容去标签化
下面就以2017年8月份上海天气链接为例,讲解上面的三个函数的应用原则:
url <- 'http://lishi.tianqi.com/shanghai/201708.html'
# 发送请求,并抓取源代码
library(rvest)
page <- html_session(url)
# 查看请求结果
page$response
# 根据标签抓取目标数据
info <- html_nodes(page, 'div.tqtongji2 > ul')
info
看见了吧,除了第一行是原始网页中的表头,第二行开始,就是我们需要的数据啦。接下来,通过html_text函数,将ul之类的标签去除即可。
# 去标签化
content <- html_text(info[-1])
content
红框中的内容就是去标签后的目标数据啦,而非红框部分的\t\n\r就是代表空白,接下来我们利用这些空白作为分隔符,将数据清洗干净。
library(stringr)
# 通过正则表达式\\s,将空白作为分隔符
cells <- sapply(content, str_split, '\\s', USE.NAMES = FALSE)
cells
你会发现,每一个日期对应的天气数据,在列表元素中所在的位置均一样,故可以通过索引获取指定的值。你可能会问,把这些空字符串删除,剩下的不就是需要的数据了吗?其实,我试过,但有错误,原因就是有些日期的指标值存在缺失。假如,8月1日,最高气温35度缺失,这个时候,第二个值及剩余的值都会往前挪一个位置,最终导致抓取下来的数据产生错位。
# 取出日期
date <-sapply(cells,'[',1)
# 取出最高温度
high <-sapply(cells,'[',15)
# 取出最低温度
low <-sapply(cells,'[',23)
# 取出天气
weather <-sapply(cells,'[',31)
# 取出风向
direction <-sapply(cells,'[',39)
# 取出风力
force <-sapply(cells,'[',47)
# 数据合并到数据框中
df <- data.frame(date, high, low, weather, direction, force)
head(df)
是不是很简单,这样就可以把2017年8月份的网页数据给抓取下来了,如果需要抓取历史更多的数据,只要改变抓取的URL链接即可。经过比对不同月份的URL发现,链接中http://lishi.tianqi.com/shanghai/201708.html的日期在变,其他部分都不变,所以,我们就可以通过循环的方式,生成这些有规律的URL。
# 生成爬取的链接
string <- 'http://lishi.tianqi.com/shanghai/'
urls <- NULL
for (year in 2011:2017){
for (month in 1:12){
if (month<10){
urls = c(urls,paste0(string,year,0,month,'.html'))
} else{
urls = c(urls,paste0(string,year,month,'.html'))
}
}
}
接下来,只需要通过循环的方式,抓取上面生成的这些链接即可。
# 从以上的每个链接中抓取天气的信息
tot_info <- data.frame()
for (url in urls){
# 发送请求并下载网页源代码
page = html_session(url)
# 根据源代码标签获取数据
info = html_nodes(page, 'div.tqtongji2 > ul') %>% html_text()
# 数据清洗--去除所有空格
info = sapply(info, str_split, '\\s', USE.NAMES = FALSE)[-1]
# 取出日期
date = sapply(info,'[',1)
# 取出最高温度
high = sapply(info,'[',15)
# 取出最低温度
low = sapply(info,'[',23)
# 取出天气
weather = sapply(info,'[',31)
# 取出风向
direction = sapply(info,'[',39)
# 取出风力
force = sapply(info,'[',47)
# 构建数据框
df = data.frame(date, high, low, weather, direction, force)
# 数据合并
tot_info = rbind(df, tot_info)
}
# 观察数据集前6行
head(tot_info)
很快,我们就抓取了上海近7年的天气数据,一共包含2422天的数据。接下来,你就可以照着上面的步骤,运用R语言实现数据的抓取啦。
下一期,我们会继续运用这个数据,通过ggplot2包实现数据的可视化,完成数据的探索性分析,期待你的加入和学习。
每天进步一点点2015
学习与分享,取长补短,关注小号!
长按识别二维码 马上关注