【Tidyverse优雅编程】R语言爬虫:哈尔滨历史天气数据
看到一篇 Python
天气网爬取历史天气的文章,我只能说:代码太罗嗦了!下面改用 R语言
来练练手。
一 . 先来看一下网页
天气网哈尔滨历史天气链接页:lishi.tianqi.com/haerbi
点开2022年03月天气:lishi.tianqi.com/haerbi
虽然看起来是表格,但 html
代码并不是 table(是就超级简单了),只能是借助正则表达式来解析了,当然也离不开我一直提倡的tidyverse
优雅数据思维:
library(tidyverse)
library(rvest)
二. 接着来获取网址
方法1,从网页解析出来
postfix = read_html("http://lishi.tianqi.com/haerbin/index.html") %>%
html_elements("a") %>%
html_attr("href") %>% # 解析网址
str_subset("^/haerbin") # 筛选出正确的
urls = str_c("http://lishi.tianqi.com/", postfix)
方法2,按规律手动生成
prefix = "http://lishi.tianqi.com/haerbin/"
Months = map(2011:2021, ~ str_c(.x, sprintf("%02d", 1:12))) %>% # 按规律生成年月
unlist()
Months = c(Months, "202201", "202202","202203","202204")
urls = str_c(prefix, "/", Months, ".html") # 若要颠倒顺序,用rev()
结果略,比解析的多两个,一个是2022年4月,一个是2020年6月(网站漏下了)。
三. 先解决一个网页的爬取+整理
(1) 从网页解析历史天气数据
weather = read_html(urls[1]) %>% # 2022年3月
html_nodes(".thrui") %>%
html_text2()
weather
结果是一个大字符串,犹如乱码。
(2)借助正则表达式+tidyverse,清洗成整洁数据框
分割成多行,一个样本一行
每一行再分割成多列
tibble(weather) %>%
separate_rows(weather, sep = "\n\r\n(?=\\d{4})") %>%
mutate(weather = str_replace_all(weather, "\r\n|查看更多", "")) %>%
separate(weather, sep = "\n\r*", extra = "drop",
into = c("日期","最高气温","最低气温","天气","风向"))
解释说明:
先用
"\n\r\n"
分割成多行,加个零宽断言(?=\\d{4})
是为了避免把\n\r\n查看更多
也给断行;将多余的
\r\n
或查看更多
替换成空以
\n
+0个或多个\r
为分隔符,将1列分割成多列参数
extra = "drop"
,是避免输出一个没有什么影响的警告消息
结果数据框如下:
四. 批量爬取多个网址
将上面爬取一个网页+整理的过程,封装成一个函数:
crawlurl = function(url) {
Sys.sleep(sample(5,1)) # 增加随机等待1-5秒
weather = read_html(url) %>%
html_nodes(".thrui") %>%
html_text2()
tibble(weather) %>%
separate_rows(weather, sep = "\n\r\n(?=\\d{4})") %>%
mutate(weather = str_replace_all(weather, "\r\n|查看更多", "")) %>%
separate(weather, sep = "\n\r*", extra = "drop",
into = c("日期","最高气温","最低气温","天气","风向"))
}
对解析生成的网址urls
,借助map
循环迭代,完成批量爬虫:
harbin = map_dfr(urls, crawlurl)
harbin
写出到Excel
文件:
writexl::write_xlsx(harbin, "哈尔滨历史天气数据.xlsx")
完工!
最后,完整代码再放一遍:
library(tidyverse)
library(rvest)
## 解析索引页, 获取批量网址
postfix = read_html("http://lishi.tianqi.com/haerbin/index.html") %>%
html_elements("a") %>%
html_attr("href") %>% # 解析网址
str_subset("^/haerbin") # 筛选出正确的
urls = str_c("http://lishi.tianqi.com/", postfix)
## 自定义函数爬取一个网页, 并清洗数据
crawlurl = function(url) {
Sys.sleep(sample(5,1)) # 增加随机等待1-5秒
weather = read_html(url) %>%
html_nodes(".thrui") %>%
html_text2()
tibble(weather) %>%
separate_rows(weather, sep = "\n\r\n(?=\\d{4})") %>%
mutate(weather = str_replace_all(weather, "\r\n|查看更多", "")) %>%
separate(weather, sep = "\n\r*", extra = "drop",
into = c("日期","最高气温","最低气温","天气","风向"))
}
## 批量爬取, 并保存到文件夹
harbin = map_dfr(urls, crawlurl)
writexl::write_xlsx(harbin, "哈尔滨历史天气数据.xlsx")
附录
我的 R 语言新书:
张敬信:《R语言编程—基于tidyverse》新书信息汇总686 赞同 · 82 评论文章695 赞同 · 85 评论文章707 赞同 · 85 评论文章719 赞同 · 86 评论文章722 赞同 · 87 评论文章729 赞同 · 87 评论文章730 赞同 · 88 评论文章825 赞同 · 99 评论文章824 赞同 · 99 评论文章
已经进入出版流程,预计 22年夏 能与读者见面。更多相关资源请参阅:
张敬信:《R语言编程:基于tidyverse》同类资源汇总36 赞同 · 0 评论文章