【问题标题】:KeyError after 10 hours of looping循环 10 小时后出现 KeyError
【发布时间】:2013-05-10 10:02:48
【问题描述】:

在以下脚本循环 15 秒后,我在以下脚本中收到以下 KeyError,完美运行了 10 个小时左右。为什么每 15 秒运行一次关键错误,却在 10 小时内只出现一次?

错误:

Traceback (most recent call last):

  File "C:\venderFix.py", line 33, in <module>

    if j['results']:

KeyError: 'results'

代码:

import json
import urllib
from pprint import pprint
import time
from arduino import Arduino

vendtime = 0.2                                           
delayTime = 15                                               
searchTerm = 'happy'                      

A = Arduino('COM3') #This will need to be COM3               
A.output([12]) #Output on pin 12                             

countTweet = 0
#To test Twitter for consistancy 
tweet= 0
noTweet= 0



#the infinate loop
while True:

    #j contains the JSON we load from the URL
    j =json.loads(urllib.urlopen('http://search.twitter.com/search.json?q='+searchTerm+'&result_type=recent&rpp=1&filter:retweets').read())

    #Debug JSON from twitter (for faults on the Twitter end or possible GET limit id below 15 seconds per request)
    #pprint(j) #needed for debugging only

    #find the text and the tweet id
    if j['results']:
        text = j['results'][0]['text']
        id = j['results'][0]['id']
        #how many times the Json is complete
        tweet+= 1
    else:
        #How many times the Json is incomplete (sometimes twitter malfunctions. About 0.1 in 100 are broken)
        noTweet += 1

    #print the text and id to the screen
    pprint(text) #needed for debugging only
    pprint(id)   #needed for debugging only

    #to get the existing tweet from before we power on, if the first ID has been stored already (count == 1)
    if countTweet != 0:  #if countTweet is not equal to 0 then it's not the first tweet
        #pprint ("new loop") #needed for debugging only

        #if lastID is not equal to ID
        if lastID != id:
        #Tell Arduino to Vend
            #pin 12 HIGH
            A.setHigh(12)
            #Sleep for the time specified in vendtime
            time.sleep(vendtime)
            #pin 12 LOW
            A.setLow(12)
            #Display the tweet that triggered the vend
            #pprint(text) #needed for debugging only
            #pprint(id)   #needed for debugging only
            #Make lastID equal to ID so that next time we can compare it 
            lastID = id
            #pprint ('lastID updated') #needed for debugging only
        #if no new tweets, print     
        else:  #needed for debugging only
            pprint ('no new tweets') #needed for debugging only
    #If it's the first loop, confirm by printing to the screen
    else:
        pprint("First loop complete")
        pprint(text)
        pprint(id)
        lastID = id
        pprint(lastID)
        countTweet += 1 #Add 1 to countTweet

    pprint ('Number of Tweets')
    pprint (countTweet)
    pprint('Working JSON')
    pprint(tweet)
    pprint('Broken JSON')
    pprint(noTweet)

    pprint('waiting')
    time.sleep(delayTime)

【问题讨论】:

  • 使用j.get('results', False)会更安全
  • 为什么每 10 小时一次?因为服务器发送错误响应平均需要很长时间。在 except 块中打印有问题的 JSON;我打赌它格式不正确

标签: python keyerror


【解决方案1】:

只是因为在那次迭代中,您的 dict 中没有密钥 results

测试一个键是否在字典中的正确方法是:

if 'result' in j:
     .... 

如果您还想检查它的值是否不是None 或任何其他虚假值,那么:

if 'result' in j and j['result']:
    ...

另一个与您正在调用服务的事实相关的假设是,服务器不时会返回一条错误消息。

如果发生这种情况,JSON 结构可能不是您所期望的,您应该检查文档是否对此有任何说明并进行相应处理。

【讨论】:

  • 我遇到了同样的问题,即在我需要使用它之前没有填充字典。上述解决方案完美运行。谢谢@pcalcao ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2014-11-25
  • 2020-02-14
相关资源
最近更新 更多