0

我正在发出几千个网络请求,但我无法一次完成所有请求。在 a 的情况下,我如何保存我的位置,可能使用tryand ?我想使用五分钟,或者发生错误时,然后从中断的地方继续。我不知道如何从中断的地方继续。我考虑过制作一个列表,然后从中弹出元素,但这似乎很麻烦。有什么建议么?excepturllib2.HTTPError: HTTP Error 400: Bad Requesttime.sleep

这是我的代码的主要内容:

with open('csvlist.csv', 'rb') as data:
    reader = csv.reader(data)
    for row in reader:
        retrieveAdd(row[0])

WhereretrieveAdd发出 Web 请求并将一些数据添加到数据库中。我尝试在每 100 个请求后睡觉(如下),但它没有用。

with open('csvlist.csv', 'rb') as data:
    reader = csv.reader(data)
    count = 0
    for row in reader:
        retrieveAdd(row[0])
        count += 1
        if count % 100 == 0:
            time.sleep(180)
4

2 回答 2

2

文件对象和csv.reader对象一起已经在跟踪它们的位置,所以如果你只是在该with语句中的某个地方处理异常,你可以for row in reader:再次循环,它会从中断的地方开始。

举一个非常愚蠢的例子:

with open('csvlist.csv', 'rb') as data:
    reader = csv.reader(data)
    ireader = enumerate(reader)
    try:
        for i, row in ireader:
            print('Read row #{}'.format(i))
            if i == 10:
                raise ValueError("I don't like the 10th row")
    except Exception as e:
        print('Raised {}'.format(e))
    for i, row in ireader:
        print('Read row #{}'.format(i))

(如果不明显:如果文件是可恢复的,并且csv.reader围绕该文件的包裹是可恢复的,那么enumerate包裹在 that 周围也是如此csv.reader,正如 Eric 在评论中指出的那样。)


当然,如果你可以在for循环中处理异常,你甚至不需要这个:

with open('csvlist.csv', 'rb') as data:
    reader = csv.reader(data)
    for i, row in enumerate(reader):
        try:
            print('Read row #{}'.format(i))
            if i == 10:
                raise ValueError("I don't like the 10th row")
        except Exception as e:
            print('Raised {}'.format(e))

在你的情况下,我看不出你不能这样做的任何理由。


如果你真的需要在更高级别处理异常,唯一有保证的安全解决方案是记住你有多少行并跳过那么多行......但是使用tellandseek方法适用于我可以访问的每个 Python,并且很可能对csv模块的任何合理实现都是安全的。因此,每次通过循环时,将data.tell()可在. (你甚至可以放入一个文本文件/pickle/数据库/任何东西,这样你就可以退出这个过程并从你离开的地方继续。)exceptdata.seek(stash)readerstash

于 2013-10-23T21:08:03.660 回答
1

为什么不将“5 分钟后重试”操作包装在一个函数中?

def retrieveAddSafe(data, repeat=5):
    """ Attempts to retrieve `data`, swallowing HTTPErrors `repeat` times before
    throwing"""
    for _ in xrange(repeat - 1):
        try:
            return retrieveAdd(data)
        except urllib2.HTTPError:
            time.sleep(5 * 60)

    # if it fails after `repeat` times, allow the error to be raised
    return retrieveAdd(data)

with open('csvlist.csv', 'rb') as data:
    reader = csv.reader(data)
    for count, row in enumerate(reader):
        retrieveAddSafe(row[0])
于 2013-10-23T21:11:15.427 回答