Python:如何修复此代码以使其在Windows上运行?

0 投票
2 回答
509 浏览
提问于 2025-04-17 06:09
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

如果我把多进程的部分去掉,程序就能正常运行。如果我在下载功能里不调用浏览器,程序也能正常运行。不过,看起来多进程和mechanize一起用就是不行。

我该怎么解决这个问题呢?在Linux系统下是不会出现这个问题的。

2 个回答

0

我建议你可以尝试以下几种方法:

  • 去掉 browser = None 这一行,或者
  • __name__=="__main__" 里的代码放到一个叫 main() 的函数里,并在 browser=mechanize.Browser() 之前加上 global browser,或者
  • 把初始化 browser 的代码放到一个叫 initializer 的地方。

如果你的任务主要是处理输入输出(I/O),那么其实不一定需要用 multiprocessing 来同时发送请求。比如,你可以使用 concurrent.futures.ThreadPoolExecutorgevent 或者 Twisted 来实现。

相关内容: 多线程Python应用和socket连接的问题

0

只有主进程会执行这个被称为 if __name__ == '__main__' 的代码块。因为Windows系统没有像其他系统那样的“分叉”功能,所以在进程池中创建的每个进程都需要自己独立的浏览器。你可以通过一个初始化函数来实现这一点。具体可以参考 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()

撰写回答