2012-06-29 5 views
0

я следующий код:питон urllib2 заклинивание 5 секунд после 6 ГЭТ, и застрял через 2 секунды после каждого POST

def whatever(url, data=None): 
    req = urllib2.Request(url) 
    res = urllib2.urlopen(req, data) 
    html = res.read() 
    res.close() 

Я пытаюсь использовать его для GET, как это:

for i in range(1,20): 
    whatever(someurl) 

затем, после того, как первые 6 раз ведут себя правильно, то он блокирует в течение 5 секунд, и по-прежнему работает нормально для отдыха получает:

2012-06-29 15:20:22,487: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:22,507: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:22,528: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:22,552: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:22,569: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:22,592: Clear [127.0.0.1:49967]: 
**2012-06-29 15:20:26,486: Clear [127.0.0.1:49967]:** 
2012-06-29 15:20:26,515: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,555: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,586: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,608: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,638: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,655: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,680: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,700: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,717: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,753: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,770: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,789: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,809: Clear [127.0.0.1:49967]: 
2012-06-29 15:20:26,828: Clear [127.0.0.1:49967]: 

При использовании-, то каждый запрос застревает 2 секунды. Я попробовал urllib2 и pycurl, они оба дают одинаковый результат.

У кого-нибудь есть представление об этом поведении?

ответ

1

Другим способом повышения производительности является использование резьба:

import threading, urllib2 
import Queue 

def read_url(url, queue): 
    data = urllib2.urlopen(url).read() 
    print('Fetched %s from %s' % (len(data), url)) 
    queue.put(data) 

def fetch_parallel(): 
    result = Queue.Queue() 
    threads = [threading.Thread(target=read_url, args = (url,result)) for url in urls_to_load] 
    for t in threads: 
     t.start() 
    for t in threads: 
     t.join() 
    return result 

def fetch_sequencial(): 
    result = Queue.Queue() 
    for i in xrange(1, 20): 
     read_url("http://www.stackoverflow.com", result) 
    return result 

дает мне [Законченный в 0.2s].

P.S., если вам не нужен список, используйте xrange вместо range. Explanation

+1

Это помогает, но не является основной причиной проблемы. Я нашел, что последняя причина заключалась в том, что pycurl не был потокобезопасным .. переключитесь на urllib2, и использование многопоточных решений решает мою проблему. – pinkdawn

0

Проблема в DNS-резольвере.

Вот good explanation

Вы можете использовать инструмент, как this и, как я полагаю, любой другой DNS распознаватель будет решить проблему.

+0

Вы действительно уверены? потому что я использую ip-адрес здесь. [127.0.0.1:49967] – pinkdawn

+0

На самом деле, на моем локальном сервере, используя ваш код, все было в порядке ([Готово в 0.9s] все 20 запросов). И поскольку вы использовали оба инструмента, и оба инструмента дают одинаковый результат, я полагаю, проблема в сервере. – maxwell

+0

Я использую этот код в контексте django, и pycurl плохо работает под многопоточным (возможно, его использует собственный код), я переключаюсь на urllib2 и используя @async из [decorator @async] (http: // micheles.googlecode.com/hg/decorator/documentation.html#async) – pinkdawn