执行天气服务代码时的Python TypeError

时间:2017-09-23 10:27:54

标签: python json beautifulsoup

我正在使用天气API来设计使用python的slack bot服务。

我的源代码是 -

import requests
import re
import json
from bs4 import BeautifulSoup


def weather(cityname):
    cityid = extractid(cityname)
    url = "http://api.openweathermap.org/data/2.5/forecast?id=" + str(cityid) + "&APPID=c72f730d08a4ea1d121c8e25da7e4411"
    while True:
        r = requests.get(url, timeout=5)
        while r.status_code is not requests.codes.ok:
            r = requests.get(url, timeout=5)
        soup = BeautifulSoup(r.text)
        data = ("City: " + soup.city["name"] + ", Country: " + soup.country.text + "\nTemperature: " + soup.temperature["value"] +
    " Celsius\nWind: " + soup.speed["name"] + ", Direction: " + soup.direction["name"] + "\n\n" + soup.weather["value"])
    # print data
    return data


def extractid(cname):
    with open('/home/sourav/Git-Github/fabulous/fabulous/services/city.list.json') as data_file:
    data = json.load(data_file)
    for item in data:
        if item["name"] == cname:
            return item["id"]


def on_message(msg, server):
    text = msg.get("text", "")
    match = re.findall(r"~weather (.*)", text)
    if not match:
        return
    searchterm = match[0]
    return weather(searchterm.encode("utf8"))


on_bot_message = on_message

但执行代码会出现以下错误 -

 File "/usr/local/lib/python2.7/dist-packages/fabulous-0.0.1-py2.7.egg/fabulous/services/weather.py", line 19, in weather
" Celsius\nWind: " + soup.speed["name"] + ", Direction: " + soup.direction["name"] + "\n\n" + soup.weather["value"])
TypeError: 'NoneType' object has no attribute '__getitem__'

我无法弄清楚错误是什么。请帮忙!

1 个答案:

答案 0 :(得分:0)

当您要求__getitem__转换为a['abc']

等词典键时,会调用

a.__getitem__('abc')

所以在这种情况下,soup的一个属性是Nonespeeddirectionweather

确保您的r.text包含您想要的数据,只需打印它:

print(r.text)

解析数据中的列表结构:

for child in soup.findChildren():
    print child

始终假设您的输入数据可能有误,而是执行soup.city执行soup.find('city'),它可能为空,所以:

city = soup.find('city')
if len(city):
   city_name = city[0]['name']
else:
   city_name = 'Error' # or empty, or sth