2012-02-16 5 views
0

저는 방금 일부 파이썬 코드를 상속했으며 가능한 빨리 버그를 수정해야합니다. 파이썬 지식이 거의 없으므로 제 인식을 용서하십시오. urllib2을 사용하여 웹 페이지에서 데이터를 추출합니다. socket.setdefaulttimeout(30)을 사용 했음에도 불구하고 여전히 겉으로는 무기한으로 늘어져있는 URL을보고 있습니다.Python 2.4에서 urllib2 urlopen 연산을 타이밍 아웃

나는 추출을 시간이 초과 할이 훨씬 후 많은 검색 웹을 가지고있다 :

시간이 경과하지만 난 그것을 중지하는 얻는 방법을 모르는 후 핸들러 함수 트리거
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() 전역 설정의 timeout 인수가 내 시스템에서이 문제점을 감지하지 못합니다.

나는 여러 가지 해결책을 시도했지만, 결국에는 파이썬 2.7로 업 그레 이드되었고, 아래의 워너 (Werner) 응답의 변형을 사용했다. 감사합니다 베르너.

+0

당신이에'timeout' 매개 변수를 의미하는 ['urllib2.urlopen()'(http://docs.python.org/library/urllib2.html#urllib2. urlopen), 나는 추정한다. 이상하다, 일해야한다. –

+0

나는 파이썬 2.4를 사용하고 있으므로 타임 아웃 옵션을 사용할 수 없다고 생각합니다. 대신 가져 오기 소켓 socket.setdefaulttimeout (30)을 사용하여 전역으로 설정합니다. – Columbo

답변

2

당신은 신호를 사용하여이 작업을 수행 할 수 있습니다.

다음은 각 기능의 타임 아웃을 설정하는 데 사용할 수있는 신호 데코레이터의 예입니다.

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' 
+0

신호의 타임 아웃이 프로세서 시간의 영향을 받습니까? 나는이 질문의 저자와 같은 타이머 스레드를 아무런 성공없이 사용하려고 시도했다. 귀하의 솔루션이 동일한 동작에 의해 영향을 받는지 궁금합니다 –

2

바로 거기 in the function입니다.

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

예컨대 :

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

시간 초과 매개 변수는 2.6 이후 사용할 수 있습니다. –

+0

@DiegoNavarro OP가 2.4를 사용한다는 사실은이 답변을 게시 할 때까지 지정되지 않았습니다. –