如果存在Traceback错误,如何保持程序运行

时间:2014-05-04 16:01:35

标签: python json reddit

我制作了一个简单的amusment脚本,它接受http://www.reddit.com/r/random/comments.json?limit=1的最新评论,并通过espeak发表讲话。然而我遇到了一个问题。如果Reddit无法给我json数据(它通常会这样做),脚本会停止并给出回溯。这是一个问题,因为它会停止脚本。如果加载失败,有没有办法重试获取json。我正在使用请求,如果这意味着什么

如果需要,以下是获取json数据的代码部分

url = 'http://www.reddit.com/r/random/comments.json?limit=1'
r = requests.get(url)
quote = r.text
body = json.loads(quote)['data']['children'][0]['data']['body']
subreddit = json.loads(quote)['data']['children'][0]['data']['subreddit']

1 个答案:

答案 0 :(得分:3)

对于词汇表,您遇到的实际错误是由于检测到运行时错误而在程序中的某个点抛出的异常; traceback 是程序线程,它告诉你 引发了异常。

基本上,你想要的是一个exception handler

try:
    url = 'http://www.reddit.com/r/random/comments.json?limit=1'
    r = requests.get(url)
    quote = r.text
    body = json.loads(quote)['data']['children'][0]['data']['body']
    subreddit = json.loads(quote)['data']['children'][0]['data']['subreddit']
except Exception as err:
    print err

这样你就可以跳过那些需要能够工作的东西的部分。也请查看该文档:https://wiki.python.org/moin/HandlingExceptions

正如pss建议的那样,如果你想在url加载失败后重试:

done = False
while not done:
    try:
        url = 'http://www.reddit.com/r/random/comments.json?limit=1'
        r = requests.get(url)
    except Exception as err:
        print err
    done = True
quote = r.text
body = json.loads(quote)['data']['children'][0]['data']['body']
subreddit = json.loads(quote)['data']['children'][0]['data']['subreddit']

N.B。:该解决方案可能不是最佳解决方案,就好像您已离线或网址总是失败一样,它会做一个无限循环。如果你重试太快,太多reddit也可能会禁止你。

N.B.2:我使用最新的python 3语法进行异常处理,这可能不适用于早于2.7的python。

N.B.3:您可能还需要为Exception选择另一个类进行异常处理,以便能够选择要处理的错误类型。它主要取决于您的应用程序设计,并且根据您的说法,您可能希望处理requests.exceptions.ConnectionError,但请查看request's doc以选择正确的。{/ p>

编辑,这是您可能想要的内容,但请仔细考虑并根据您的使用情况进行调整:

import requests
import time
import json

def get_reddit_comments():
    retries = 5
    while retries != 0:
        try:
            url = 'http://www.reddit.com/r/random/comments.json?limit=1'
            r = requests.get(url)
            break  # if the request succeeded we get out of the loop
        except requests.exceptions.ConnectionError as err:
            print("Warning: couldn't get the URL: {}".format(err))
            time.delay(1) # wait 1 second between two requests
            retries -= 1
            if retries == 0: # if we've done 5 attempts, we fail loudly
                return None
    return r.text

def use_data(quote):
    if not quote:
        print("could not get URL, despites multiple attempts!")
        return False

    data = json.loads(quote)        

    if 'error' in data.keys():
        print("could not get data from reddit: error code #{}".format(quote['error']))
        return False

    body = data['data']['children'][0]['data']['body']
    subreddit = data['data']['children'][0]['data']['subreddit']

    # … do stuff with your data here

if __name__ == "__main__":
    quote = get_reddit_comments()
    if not use_data(quote):
        print("Fatal error: Couldn't handle data receipt from reddit.")
        sys.exit(1)

希望此代码段可以帮助您正确设计您的程序。现在您已经发现了Exceptions,请务必记住例外情况是处理特殊的事情。如果你在某个程序中的某个时刻抛出异常,总是问自己这是否是在发生意外情况时会发生的事情(如网页未加载),或者它是否是预期的错误(如页面)加载,但给你一个不期望的输出。)