有时候出于某种目的,我们可能需要从一些网站获取一些数据。如果网站提供了下载选项,那么我们可以直接从网站下载,当然有些网站可能只是提供日常更新,而没有提供下载选项的话,就要另想办法了。
如果只是突然要从某网站获取一次数据,那么即使没有提供下载,只要复制粘贴即可。如果需要的数据量很大,复制粘贴太耗时,又或是要经常从某网站获取一些数据,那么就要想(码)办(代)法(码)了。
既然是气象人,那么本例就以下载怀俄明大学提供的探空数据为例,讲一下如何从某网站下载数据。
打开网站之后,我们看到一些选项可以选择区域,日期及站点。
绘图类型提供了很多选项
但这里我们只是下载探空数据,选择 Text:List 即默认选项即可。而我们通常需要的是国内的探空数据,因此,在 Region 项选择 Southeast Asia 即可。
站点栏输入 58238。如果你知道站点号,可以直接输入,不知道的话,可以在地图中直接点击站点号。
然后回车就可以看到探空数据页了
因为我们只选了一个时次的,所以只有一个时刻的探空信息。而且,从网页给出的数据可以看出,给出的信息非常清晰,基本上只有探空数据和一些计算后的指标。
右击探空数据页,查看网页源代码:
可以看到,我们能用到的信息为 H2,PRE,H3标签所对应的信息,而PRE标签对应了探空数据和站点信息及探空指标信息。
获取网页地址,然后就可以直接从网页下载数据了。
所用库: BeautifulSoup4,requests
import requests
from bs4 import BeautifulSoup
url = 'http://weather.uwyo.edu/cgi-bin/sounding?region=seasia&TYPE=TEXT%3ALIST&YEAR=2017&MONTH=06&FROM=2112&TO=2112&STNM=58238'
# 使用requests 获取网页数据,然后用 BeautifulSoup 解析网页
data = BeautifulSoup(requests.request('get', url).text, 'lxml')
# 打印 站点信息
print(data.h2.string)
# 打印探空数据
print(data.pre.get_text())
# 保存探空数据到文件
uppair = open(r'F:\uppair.txt', 'w')
print(data.pre.get_text(), file = uppair)
# 一定要关闭
uppair.close()
这样探空数据就下载下来了
-----------------------------------------------------------------------------
PRES HGHT TEMP DWPT RELH MIXR DRCT SKNT THTA THTE THTV
hPa m C C % g/kg deg knot K K K
-----------------------------------------------------------------------------
1000.0 7 26.0 22.7 82 17.72 115 6 299.1 351.1 302.3
925.0 720 21.4 18.4 83 14.62 150 16 301.2 344.4 303.8
850.0 1449 17.4 11.4 68 10.05 130 17 304.4 334.7 306.2
700.0 3084 9.2 -1.8 46 4.81 100 19 312.6 328.1 313.6
500.0 5790 -4.9 -12.9 53 2.85 280 17 327.0 336.9 327.6
400.0 7510 -16.5 -21.0 68 1.80 280 39 333.5 340.0 333.8
300.0 9600 -32.7 -43.7 33 0.27 260 62 339.2 340.3 339.2
250.0 10870 -40.3 -56.3 16 0.07 250 85 346.0 346.4 346.0
220.0 11724 -46.3 -61.7 16 0.04 245 91 349.7 349.9 349.7
200.0 12360 -50.7 -65.7 15 0.03 250 89 352.3 352.5 352.3
150.0 14180 -62.3 250 78 362.6 362.6
118.0 15633 -70.3 270 64 373.6 373.6
100.0 16620 -68.9 270 47 394.4 394.4
70.0 18750 -64.7 305 10 445.6 445.6
50.0 20820 -58.3 105 10 505.7 505.7
30.0 24060 -53.7 80 21 597.6 597.6
20.0 26700 -48.9 90 33 685.7 685.7
你以为到现在就结束了码?如果每次都这样手动确定网页的URL,那和复制粘贴有什么区别呢?为了以后能后省却很多时间,我们看一下网页URL的特点:
http://weather.uwyo.edu/cgi-bin/sounding?region=seasia&TYPE=TEXT%3ALIST&YEAR=2017&MONTH=06&FROM=2112&TO=2112&STNM=58238
URL中有 region,TYPE,YEAR,MONTH,STNM,而针对天的选择是由 FROM 和 TO控制的。分别对应了选择网页选择地区,日期,站点等信息时的每一个选项。
东南亚的 region 值为 seasia ,而北美的 region 值为 naconf ,但在下载数据时,真正控制所选探空数据的是 站点,日期信息。地区信息并不重要。
所以,后面在选择下载探空数据时,只要根据需要修改URL就行了。比如,想获取 2017.6.20 8:00 到 2017.6.22 8:00 的探空数据,URL应为:
http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST&YEAR=2017&MONTH=06&FROM=2000&TO=2200&STNM=58238
注意:探空时间均为UTC时间。同时,注意 region 值为 naconf,同样可以获取到正确的探空数据。2000 对应的时间分别为天和小时,前两位对应天,后两位对应小时。
细心的你可能发现了,上面打印 PRE 标签信息的时候,打印的是探空信息,但是打印时并没有指定索引。这就是问题了:如果同一个标签对应了多个信息的话,那么默认获取的就是第一个信息。要获取所有信息,可以使用 fing_all 方法。
print(data.find_all('pre')[1].string)
Station identifier: ZSNJ
Station number: 58238
Observation time: 170621/1200
Station latitude: 32.00
Station longitude: 118.80
Station elevation: 7.0
Showalter index: 4.27
Lifted index: -1.30
LIFT computed using virtual temperature: -1.80
SWEAT index: 276.75
K index: 22.70
Cross totals index: 16.30
Vertical totals index: 22.30
Totals totals index: 38.60
Convective Available Potential Energy: 637.33
CAPE using virtual temperature: 813.63
Convective Inhibition: -22.85
CINS using virtual temperature: -10.14
Equilibrum Level: 243.86
Equilibrum Level using virtual temperature: 243.14
Level of Free Convection: 829.33
LFCT using virtual temperature: 884.16
Bulk Richardson Number: 1946.17
Bulk Richardson Number using CAPV: 2484.53
Temp [K] of the Lifted Condensation Level: 293.58
Pres [hPa] of the Lifted Condensation Level: 928.82
Mean mixed layer potential temperature: 299.87
Mean mixed layer mixing ratio: 16.61
1000 hPa to 500 hPa thickness: 5783.00
Precipitable water [mm] for entire sounding: 44.52
如果获取到站点信息和探空指标信息之后,想要获取对应的数值信息,那么就要用到正则表达式了。
所用库: re
import re
# 获取对流有效位能值
cape = re.findall('(?<=Convective Available Potential Energy:)(.-?\d+\.\d+)', data.text)
print(cape)
# 注意: 输出值为列表
[' 637.33']
下面,给出下载探空数据的示例程序,方便后面调用。
def get_sounding_from_uwyo(dates, station, file = None, region = 'naconf'):
"""
从怀俄明大学探空数据网站获取探空数据
参数:
dates : datetime.datetime。探空时间
station : 站点信息
file : 探空输出文件名。默认为None,即不输出到文件中。
字符串类型
region :探空数据的区域,可以不指定。默认为北美地区。
输出:
sounding : 探空数据。如果输出到文件的话,为None。
"""
import requests
from bs4 import BeautifulSoup
url = ('http://weather.uwyo.edu/cgi-bin/sounding?region={region}&TYPE=TEXT%3ALIST'
'&YEAR={time:%Y}&MONTH={time:%m}&FROM={time:%d%H}&TO={time:%d%H}'
'&STNM={stid}').format(region=region, time=dates, stid=station)
data = BeautifulSoup(requests.request('get', url).text, 'lxml')
sounding_head = data.find_all('h2')
sounding = data.find_all('pre')
sisi_head = data.find_all('h3')
if file is None:
return sounding[0].get_text()
else:
with open(file, 'w') as f:
f.write(sounding_head[0].get_text())
f.write(sounding[0].get_text())
f.close()
if __name__ == '__main__':
from datetime import datetime
dates = datetime(2017, 6, 21, 0)
station = 58238
sounding = get_sounding_from_uwyo(dates, station, file = 'sounding.txt')
print(sounding)
只给出下载探空数据的程序示例,可以根据需要添加功能。比如:获取CAPE,CIN,站点经纬度,K指数,降水量等信息。
因为不需要登录,而且信息明确,因此怀俄明大学探空数据的下载相对容易一些,而对于一些需要登录,并且信息繁杂的网站,获取信息时相对就麻烦许多。
从上面的例子中可以看出,通常需要requests,beautifulsoup4,re等库。