天气数据的爬取与可视化
引言
天气数据作为一类重要的数据资源,在各个行业有着广泛而且重要的应用。通常来说,天气预报的数据作为公共资源是非常容易获取的,但是如果想知道大范围、长时间的气象历史数据,还是需要费一番周折的。
网上也有一些可以获取历史气象数据的API,例如AccuWWeather、Darksky和OpenWeatherMap等,但是免费版的一般会限制调用次数,而收费版的并不在初学者的考虑范围之内。由于很多气象网站也提供历史数据,而网页的访问通常不限次数(只要不是太过分的话),所以为了解决这个问题,我们可以通过抓取网页,然后提取和整体我们需要的数据。
接下来我们将使用Requests, Selenium和Beautiful Soup等Python包从Wunderground网站上抓取天气数据。
准备工作
Wunderground介绍
Wunderground(https://www.wunderground.com )的全称是Weather Underground(目前属于IBM的子公司The Weather Company),Weather Underground成立于1995年,一直以来致力于为公众分享天气信息,其数据直接来源于气象站点,目前有在美国有超过18万个站点,在全世界其他国家超过29万个气象站点的气象数据,为我们获取气象数据提供了极大的便利。
Python包介绍
我们在爬取数据过程中,用到的Python包主要包括:
- Requests包,它是Python中用于发出HTTP请求的事实标准库(Python自带的urllib易用性要差一些),提供了一套简洁、优美的API处理复杂的请求;
- Beautiful Soup包,它是一个用来解析HTML或者XML文件的库,支持我们从网页中搜索、提取或者修改期望的数据;
- Selenium包,是一个用来自动化测试网络应用的包,目前许多网页是动态生成的,无法从静态页面里抓取数据,所以我们用Selenium实现动态页面的生成和加载;
- Scrapy包,是Python中的网络爬虫,用于获得气象网站的多个页面。
抓取Wunderground气象数据
数据的抓取过程可以分为一下几个步骤:
- Scrapy/Requests发出请求;
- Selenium加载网页;
- Beautiful Soup解析网页
所以,我们需要先定义一些工具:
1 | from datetime import datetime, timedelta |
定义基础工具
浏览器对象示例
1 | def get_browser(): |
selenium.webdriver
模块提供了所有WebDriver的实现,当前支持的WebDriver有: Firefox, Chrome, IE and Remote。
构造请求URL
1 | def get_url(location, day, month, year): |
Selenium加载网页
1 | def parse_page(url, browser): |
BS4解析网页
1 | # Retrieve temperature data |
爬虫示例
设置参数
1 | station = 'KSFO' |
迭代爬取页面
1 | browser = get_browser() |
天气数据可视化
我们首先看一下2018年每天气温的基本情况,以及每日的最高气温、最低气温和平均气温之间的关系:
1 | import matplotlib.pyplot as plt |
actual_mean_temp actual_min_temp actual_max_temp average_min_temp \
count 365.000000 365.000000 365.000000 365.000000
mean 59.484932 51.479452 66.975342 50.194521
std 5.907522 4.950607 7.911040 6.202000
min 45.000000 36.000000 53.000000 0.000000
25% 55.000000 48.000000 61.000000 47.000000
50% 60.000000 52.000000 67.000000 51.000000
75% 63.000000 55.000000 72.000000 55.000000
max 81.000000 64.000000 102.000000 56.000000
average_max_temp record_min_temp record_max_temp
count 365.000000 365.000000 365.000000
mean 65.317808 40.243836 83.635616
std 8.496466 6.546809 10.027782
min 0.000000 24.000000 65.000000
25% 60.000000 35.000000 74.000000
50% 67.000000 41.000000 85.000000
75% 72.000000 46.000000 92.000000
max 74.000000 50.000000 106.000000
我从GitHub上找到了一个可视化效果比较好的代码(https://github.com/fivethirtyeight ),仅供参考:
1 | # Generate a bunch of histograms of the data to make sure that all of the data |
actual_mean_temp | month | |
---|---|---|
Datetime | ||
2018-01-01 | 51 | January |
2018-01-02 | 55 | January |
2018-01-03 | 55 | January |
2018-01-04 | 58 | January |
2018-01-05 | 59 | January |
1 | import numpy as np |
其他方法
如果用Selenium去解析网页的话,最大的问题是速度太慢,如果我们仔细分析Wunderground的网页的话,可以发现网页实际上是通过API获取JSON格式的数据的。所以实际上,我们仍然可以采取调用API的方法来获得数据,至于具体的方法,我们留待以后介绍。