API调用检查是否检索到某些数据

时间:2019-06-04 07:19:44

标签: python api

我正在100个不同的城市执行100次API调用,调用时通常以以下形式出现:

onerror

但是,有时在['data'] ['iaqi']中缺少co,no2,o3等之一,却在遍及100个城市并执行api调用时,我想检查每个城市是否存在,如果不存在,请附加“ na”。

我正在尝试,除了这样:

{'data': {'aqi': 13,
          'attributions': [{'name': 'Air Quality Ontario - the Ontario '
                                    'Ministry of the Environment and Climate '
                                    'Change',
                            'url': 'http://www.airqualityontario.com/'},
                           {'name': 'World Air Quality Index Project',
                            'url': 'https://waqi.info/'}],
          'city': {'geo': [43.653226, -79.3831843],
                   'name': 'Toronto',
                   'url': 'https://aqicn.org/city/toronto'},
          'debug': {'sync': '2019-06-04T15:37:48+09:00'},
          'dominentpol': 'pm25',
          'iaqi': {'co': {'v': 1.7},
                   'no2': {'v': 15.2},
                   'o3': {'v': 8.8},
                   'p': {'v': 1018.3},
                   'pm25': {'v': 13},
                   'so2': {'v': 0.2},
                   't': {'v': 11.6},
                   'w': {'v': 0.2}},
          'idx': 5914,
 'status': 'ok'}

这工作得很好,但是似乎效率不高,我想知道是否有一种更干净的方法可以做到这一点。谢谢!

3 个答案:

答案 0 :(得分:1)

不要像这样将污染物放在单独的列表中,而是要像这样保留字典:

polutants = {"co":[],"no2":[],"so2":[],"pm25":[]}

如果您确定密钥与您希望从API中获得的密钥匹配,则可以执行以下操作:

for item in polutants.keys():
   if item in response["data"]["iaqi"].keys():
      polutants[item].append(response["data"]["iaqi"][item])
   else:
      polutants[item].append('na')

但是说实话,您的方法也很好。

答案 1 :(得分:1)

您可以改用get方法 例如:

<your_variable>.append(data["iaqi"].get("co",data["iaqi"]).get("v","na"))

答案 2 :(得分:0)

选择更好的数据结构可以使其更完善

from collections import defaultdict
cities = defaultdict(dict)
data_points = ["co", "no2", "o3", "pm25"]

for city in canadian_cities:
    url = f'https://api.waqi.info/feed/{city}/?token={api_key}'
    response = requests.get(url).json()
    if (response["status"] == "ok"):
        # sometime aqi might not be a number, exclude them
        print("yes")
        if (isinstance(response["data"]["aqi"], int)):
            # append aqi and city name to appropriate list
            cities[city]['aqi'] = response["data"]["aqi"]
            for data_point in data_points:
                cities[city][data_point] = response["data"]["iaqi"].get(data_point, dict()).get("v", "na")

print(cities)

我什至会更进一步,像这样重构它:

from collections import defaultdict, namedtuple

cities = defaultdict(dict)
data_points = ['aqi', "co", "no2", "o3", "pm25"]
defaults = ['na', 'na', 'na', 'na', 'na']
AQI = namedtuple('AQI', field_names=data_points, defaults=defaults)

def get_data(city):
    url = f'https://api.waqi.info/feed/{city}/?token={api_key}'
    response = requests.get(url).json()
    if response["status"] == "ok":
        return response

def parse_json(data):
    raw_data = {key:value['v'] for key, value in data["iaqi"].items() if key in data_points[1:]}
    raw_data['aqi'] = data["aqi"]
    return AQI(**raw_data)

for city in canadian_cities:
    data = get_data(city)
    if data and isinstance(data["data"]["aqi"], int):
        cities[city] = parse_json(data=data["data"])
print(cities)