Тайм-аут операции urllib2 urlopen в Python 2.4 - PullRequest
1 голос
/ 16 февраля 2012

Я только что унаследовал некоторый код Python и должен исправить ошибку как можно скорее.У меня очень мало знаний Python, поэтому, пожалуйста, извините за мое невежество.Я использую urllib2 для извлечения данных из веб-страниц.Несмотря на использование socket.setdefaulttimeout(30), я все еще сталкиваюсь с URL-адресами, которые кажутся бесконечно зависшими.

Я хочу установить время ожидания извлечения и добился такого большого результата после долгих поисков в Интернете:

import socket 
socket.setdefaulttimeout(30)

reqdata = urllib2.Request(urltocollect)

    def handler(reqdata):
        ????  reqdata.close() ????


    t = Timer(5.0, handler,[reqdata])
    t.start()
    urldata = urllib2.urlopen(reqdata)
    t.cancel()

Функция обработчика срабатывает по прошествии времени, но я не знаю, как заставить ее остановить операцию openurl.

Любое руководство будет с благодарностью получено.C

ОБНОВЛЕНИЕ ------------------------- По моему опыту, при использовании определенных URL-адресов urllib2.urlopen зависает и ждет бесконечно.URL-адреса, которые делают это, являются теми, на которые указывает браузер, которые никогда не разрешаются, браузер просто ждет, пока индикатор активности движется, но никогда не подключается полностью.Я подозреваю, что эти URL-адреса могут застрять внутри какого-то перенаправления бесконечного цикла.Аргумент тайм-аута для urlopen (в более поздних версиях Python) и глобальный параметр socket.setdefaulttimeout () не обнаруживают эту проблему в моей системе.

Я попробовал несколько решений, но в итоге я обновился до Python2.7 и использовал вариант ответа Вернера ниже.Спасибо Вернер.

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Вы можете достичь этого, используя сигналы.

Вот пример моего декоратора сигналов, который вы можете использовать для установки времени ожидания для отдельных функций.

Ps. не уверен, что это синтаксически правильно для 2.4. Я использую 2.6, но 2.4 поддерживает сигналы.

import signal
import time

class TimeOutException(Exception):
    pass

def timeout(seconds, *args, **kwargs):
    def fn(f):
        def wrapped_fn(*args, **kwargs):
            signal.signal(signal.SIGALRM, handler)
            signal.alarm(seconds)
            f(*args, **kwargs)
        return wrapped_fn
    return fn

def handler(signum, frame):
    raise TimeOutException("Timeout")

@timeout(5)
def my_function_that_takes_long(time_to_sleep):
    time.sleep(time_to_sleep)

if __name__ == '__main__':
    print 'Calling function that takes 2 seconds'
    try:
        my_function_that_takes_long(2)
    except TimeOutException:
        print 'Timed out'

    print 'Calling function that takes 10 seconds'
    try:
        my_function_that_takes_long(10)
    except TimeOutException:
        print 'Timed out'
2 голосов
/ 16 февраля 2012

Это прямо там в функции .

urllib2.urlopen(url[, data][, timeout])

например:

urllib2.urlopen("www.google.com", data, 5)
...