2010-01-26 4 views
8

들어오는 URL에 대한 큐를 읽는 프로세스를 설정했지만 urllib2에서 연결을 열면 시스템이 중단됩니다.Python 프로세스가 urllib2에 의해 차단되었습니다.

import urllib2, multiprocessing 
from threading import Thread 
from Queue import Queue 
from multiprocessing import Queue as ProcessQueue, Process 

def download(url): 
    """Download a page from an url. 
    url [str]: url to get. 
    return [unicode]: page downloaded. 
    """ 
    if settings.DEBUG: 
     print u'Downloading %s' % url 
    request = urllib2.Request(url) 
    response = urllib2.urlopen(request) 
    encoding = response.headers['content-type'].split('charset=')[-1] 
    content = unicode(response.read(), encoding) 
    return content 

def downloader(url_queue, page_queue): 
    def _downloader(url_queue, page_queue): 
     while True: 
      try: 
       url = url_queue.get() 
       page_queue.put_nowait({'url': url, 'page': download(url)}) 
      except Exception, err: 
       print u'Error downloading %s' % url 
       raise err 
      finally: 
       url_queue.task_done() 

    ## Init internal workers 
    internal_url_queue = Queue() 
    internal_page_queue = Queue() 
    for num in range(multiprocessing.cpu_count()): 
     worker = Thread(target=_downloader, args=(internal_url_queue, internal_page_queue)) 
     worker.setDaemon(True) 
     worker.start() 

    # Loop waiting closing 
    for url in iter(url_queue.get, 'STOP'): 
     internal_url_queue.put(url) 

    # Wait for closing 
    internal_url_queue.join() 

# Init the queues 
url_queue = ProcessQueue() 
page_queue = ProcessQueue() 

# Init the process 
download_worker = Process(target=downloader, args=(url_queue, page_queue)) 
download_worker.start() 

다른 모듈에서 URL을 추가 할 수 있으며 원하는 경우 프로세스를 중지하고 프로세스가 닫힐 때까지 기다릴 수 있습니다.

import module 

module.url_queue.put('http://foobar1') 
module.url_queue.put('http://foobar2') 
module.url_queue.put('http://foobar3') 
module.url_queue.put('STOP') 
downloader.download_worker.join() 

문제는 내가 ("응답 = urllib2.urlopen (요청)") urlopen 사용할 때 차단 된 모든 남아 있다는 것입니다.

download() 함수를 호출하거나 Process없이 스레드 만 사용할 때는 문제가 없습니다.

답변

4

여기의 문제는 urllib2가 아니라 다중 처리 모듈의 사용입니다. Windows에서 다중 처리 모듈을 사용할 때는 모듈을 가져올 때 즉시 실행되는 코드를 사용하지 말고 대신 주 모듈의 내용을 if __name__=='__main__' 블록 안에 넣어야합니다. "주 모듈의 안전 가져 오기"섹션 here을 참조하십시오.

#.... 
def start(): 
    global download_worker 
    download_worker = Process(target=downloader, args=(url_queue, page_queue)) 
    download_worker.start() 

그리고 주요 모듈 : 서브 프로세스이었다

import module 
if __name__=='__main__': 
    module.start() 
    module.url_queue.put('http://foobar1') 
    #.... 

이 작업을 수행하지 않았기 때문에, 때마다

코드에 대한

, 다운로더 모듈에서 다음이 변경 메인 코드를 다시 실행하고 다른 프로세스를 시작하여 중단을 일으켰습니다.

+0

Windows를 사용하지 않지만 start() 함수를 사용하여 문제를 해결할 것을 제안합니다. 감사! – Davmuz

관련 문제