2011-11-12 2 views
0
import lxml.html 
import mechanize, cookielib 
import multiprocessing 

browser = None 

def download(i): 
    link = 'www.google.com' 
    response = browser.open(link) 
    tree = lxml.html.parse(response) 
    print tree 
    return 0 

if __name__ == '__main__':  
    browser = mechanize.Browser() 
    cookie_jar = cookielib.LWPCookieJar() 
    browser.set_cookiejar(cookie_jar) 
    browser.set_handle_equiv(True) 
    browser.set_handle_gzip(True) 
    browser.set_handle_redirect(True) 
    browser.set_handle_referer(False) #inicialmente estava on mas deve ser melhor off 
    browser.set_handle_robots(False) 
    browser.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) 
    browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:2.0.1) Gecko/20100101 Ubuntu/11.04 maverick Firefox/4.0.1')] 

    pool = multiprocessing.Pool(None) 
    tasks = range(8) 
    r = pool.map_async(download, tasks) 
    r.wait() # Wait on the results 

다중 처리 부분을 제거하면 작동합니다. 다운로드 기능 내에서 브라우저를 호출하지 않으면 작동합니다. 그러나 다중 처리 + 기계화가 단순히 작동하지 않는 것처럼 보입니다.Python :이 코드가 Windows에서 작동하도록 수정하려면 어떻게해야합니까?

어떻게 해결할 수 있습니까? 그것은 리눅스에서 발생하지 않습니다.

답변

0

만 메인 프로세스는 게이트 if __name__ == '__main__' 블록을 실행한다. Windows에는 fork 시스템 호출이 없기 때문에 풀에 생성 된 각 프로세스에는 자체 브라우저가 필요합니다. 이니셜 라이저 기능으로이 작업을 수행 할 수 있습니다. 참조 용으로 initializerinitargs 옵션은 multiprocessing.Pool입니다.

import lxml.html 
import mechanize, cookielib 
import multiprocessing as mp 

def download(i): 
    link = 'http://www.google.com' 
    response = browser.open(link) 
    tree = lxml.html.parse(response) 
    print tree 
    return 0 

def init(count): 
    global browser 
    browser = mechanize.Browser() 
    cookie_jar = cookielib.LWPCookieJar() 
    browser.set_cookiejar(cookie_jar) 
    browser.set_handle_equiv(True) 
    browser.set_handle_gzip(True) #warning 
    browser.set_handle_redirect(True) 
    browser.set_handle_referer(False) 
    browser.set_handle_robots(False) 
    browser.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), 
           max_time=1) 
    browser.addheaders = [('User-agent', 
     'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:2.0.1) ' 
     'Gecko/20100101 Ubuntu/11.04 maverick Firefox/4.0.1')] 

    count.value -= 1 

if __name__ == '__main__': 
    import time 
    count = mp.Value('I', mp.cpu_count()) 
    pool = mp.Pool(count.value, initializer=init, initargs=(count,)) 
    #wait until all processes are initialized 
    while count.value > 0: 
     time.sleep(0.1) 

    tasks = range(8) 
    r = pool.map_async(download, tasks) 
    r.wait() 
0

내가하려고 할 것입니다 :

  • main() 기능에 browser = None 또는
  • 이동에게 __name__=="__main__"의 코드를 제거하기 전에 global browser를 추가 browser=mechanize.Browser() 또는 initializer
  • browser를 초기화
  • 이동 코드

작업이 I/O 경계에 있다면 동시 요청을 수행하기 위해 반드시 multiprocessing이 필요하지는 않습니다. 예를 들어 concurrent.futures.ThreadPoolExecutor, gevent, Twisted 대신 사용할 수 있습니다.

관련 : Problem with multi threaded Python app and socket connections

관련 문제