Python:如何修复此代码以使其在Windows上运行?
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.ThreadPoolExecutor
、gevent
或者 Twisted
来实现。
相关内容: 多线程Python应用和socket连接的问题
0
只有主进程会执行这个被称为 if __name__ == '__main__'
的代码块。因为Windows系统没有像其他系统那样的“分叉”功能,所以在进程池中创建的每个进程都需要自己独立的浏览器。你可以通过一个初始化函数来实现这一点。具体可以参考 initializer
和 initargs
这两个选项,详细信息可以查看 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()