目的:已知某一地址,获取过去某一时间该地的天气数据,并能够批量运行。
第一步:通过百度地图API获取该地址的经纬度坐标。
输入:
此处因后续要画热力图,因此附带了字段count。
代码:
import json
from urllib.request import urlopen, quote
import csv
def getlnglat(address):
url = 'http://api.map.baidu.com/geocoder/v2/'
output = 'json'
ak = 'your ak'
add = quote(address) # 防止乱码,用quote编码
uri = url + '?' + 'address=' + add + '&output=' + output + '&ak=' + ak
req = urlopen(uri)
res = req.read().decode() # 解码
temp = json.loads(res) # 对json数据解析
return temp
with open('result.json', 'w') as file: # 建立json数据文件
with open('data.csv', 'r') as csvfile: # 打开csv
reader = csv.reader(csvfile)
for line in reader: # 逐行读取数据
city = line[0].strip() # 读取城市
value = line[1].strip() # 读取数值
try:
# 获取经纬度
lng = getlnglat(city)['result']['location']['lng']
lat = getlnglat(city)['result']['location']['lat']
except KeyError:
# 如果发生键错误,则将经纬度赋值为"error"
lng = "error"
lat = "error"
str_temp = '{"lat":' + str(lat) + ',"lng":' + str(lng) + ',"count":' + str(value) + '},\r'
file.write(str_temp) # 写入文档
此段代码为经百度地图api官网样例后修改。
输出:
{"lat":45.58567523781376,"lng":84.89590053887504,"count":1}, {"lat":31.235929042252014,"lng":121.48053886017651,"count":1}, {"lat":26.032184521581936,"lng":105.7085407819862,"count":1}, {"lat":33.81734281915162,"lng":106.63566517540986,"count":1}, {"lat":37.41586507235288,"lng":117.32818631830014,"count":1}, {"lat":30.10533829713717,"lng":120.54517708011481,"count":1}, {"lat":29.243635896221726,"lng":118.37502510104238,"count":1}, {"lat":33.6238252167372,"lng":106.92741441351562,"count":1},
第二步:通过Visual Weather API获取天气数据。
输入:
此处因第一步有些位置获取坐标失败,因此为空白。
代码:
import pandas as pd
import math
import datetime
import urllib.request
import win32com.client
import winsound
# 读取原始事故数据
raw_accident_data = pd.read_csv('weatherdata.csv')
records = []
labels = ['Date', 'Latitude', 'Longitude', 'Number', 'temp', 'dew', 'humidity', 'wind speed', 'precip',
'visibility', 'cloudcover', 'type', 'conditions']
# 遍历原始事故数据的每一行
for i, row in raw_accident_data.iterrows():
latitude = row['lat']
longitude = row['lon']
documentNumber = row['number']
datetimeStr = row['date']
weather_api_endpoint = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/weatherdata/history'
# 检查经纬度是否为NaN或零值
if math.isnan(latitude) or math.isnan(longitude) or (latitude == 0 and longitude == 0):
print(i + 1, "Bad latlon {},{}".format(latitude, longitude))
records.append(('','', '', documentNumber))
continue
try:
date_time = datetime.datetime.strptime(datetimeStr, '%m/%d/%Y %H:%M')
except ValueError:
print("Bad date format {}".format(datetimeStr))
records.append(('','', '', documentNumber))
continue
latitude = '{:.5f}'.format(latitude)
longitude = '{:.5f}'.format(longitude)
query_params = '&contentType=csv&aggregateMinutes=15&unitGroup=us&includeAstronomy=true&collectStationContributions=true&key={}&startDateTime={}&endDateTime={}&locations={},{}'
query_params = query_params.format("your ak", date_time.isoformat(), date_time.isoformat(), latitude,longitude)
try:
response = urllib.request.urlopen(weather_api_endpoint + "?" + query_params)
df = pd.read_csv(response)
# 获取指定列的第一个数据
Address = df.get('Address', [''])[0]
Date = df.get('Date time', [''])[0]
Temperature = df.get('Temperature', [''])[0]
Dew_Point = df.get('Dew Point', [''])[0]
Humidity = df.get('Relative Humidity', [''])[0]
Wind_Speed = df.get('Wind Speed', [''])[0]
Precipitation = df.get('Precipitation', [''])[0]
Visibility = df.get('Visibility', [''])[0]
Cloud_Cover = df.get('Cloud Cover', [''])[0]
Weather_Type = df.get('Weather Type', [''])[0]
Conditions = df.get('Conditions', [''])[0]
except Exception:
print("Error reading from {}".format(weather_api_endpoint + "?" + query_params))
continue
# 构造记录
record = [date_time.isoformat(), latitude, longitude, documentNumber, Temperature, Dew_Point, Humidity, Wind_Speed,
Precipitation, Visibility, Cloud_Cover, Weather_Type, Conditions]
records.append(record)
print("No.", i + 1, "Finished...")
# 创建输出DataFrame并保存为CSV文件
output_df = pd.DataFrame.from_records(records, columns=labels)
output_df.to_csv('output.csv', index=False)
# 结束播放提示音
speak = win32com.client.Dispatch('SAPI.SPVOICE')
winsound.MessageBeep()
speak.Speak('程序运行完毕!')
此段代码为经Visual Weather API官网样例后修改。原代码返回数据格式为json,经测试json风速字段不可用,后改为返回数据格式为csv。
输出:
这一步也会有获取不到的时间和地点,因此为空白。
获取到的字段包括:平均温度、露点、湿度、风速、降雨量、能见度、云量、天气类型等。
若修改weather_api_endpoint,还可获取该地点的预测数据,但返回数据字段可能发生变化,请以官网文档为准。