Python Multiprocessing Manager共享列表出现NameError问题求助
搞定多进程爬取的NameError问题:Selenium共享数据的正确姿势
嘿,我一眼就看出你代码里的核心问题了——多进程的内存隔离特性坑了你!父进程里定义的scrapedinfo全局变量,子进程根本看不到,这就是为啥会报scrapedinfo is not defined的错。再加上你的爬取逻辑根本没被调用,自然啥数据也存不上。
下面是修复后的完整代码,我给你逐点讲清楚改动:
from selenium import webdriver from multiprocessing import Pool, Manager def browser(): driver = webdriver.Chrome() return driver # 改动1:把共享列表作为参数传入爬取函数,再也不用依赖全局变量 def scrape_stuff(driver, scraped_list): # 这里替换成你的实际爬取逻辑,比如先拿个页面标题做示例 page_title = driver.title scraped_list.append(page_title) # 改动2:修改test_func,接收打包好的参数(链接+共享列表) def test_func(task_args): link, scraped_list = task_args driver = browser() try: # 修复了原链接里的小问题:example.com要加https:// driver.get(link) # 调用爬取函数,把共享列表传进去 scrape_stuff(driver, scraped_list) finally: # 不管爬取成功失败,都要关闭浏览器,避免残留进程占资源 driver.quit() def multip(): manager = Manager() # 用Manager创建共享列表,这个没问题 scrapedinfo = manager.list() links = ["https://stackoverflow.com/", "https://signup.microsoft.com/", "https://www.example.com"] # 改动3:把每个链接和共享列表打包成元组,因为pool.map只能传单个参数 tasks = [(link, scrapedinfo) for link in links] # 改动4:用with语句管理进程池,自动帮你关闭池,不用手动close/join with Pool(processes=3) as pool: pool.map(test_func, tasks) # 把manager.list转成普通列表打印,看起来更直观 print("最终爬取结果:", list(scrapedinfo)) # 改动5:Windows系统下多进程必须加这个判断,否则会触发重复初始化的bug if __name__ == "__main__": multip()
为啥这么改?给你划重点:
- 放弃全局变量传共享对象:多进程之间内存是完全隔离的,父进程的全局变量到子进程里就是空的,直接传参数才是靠谱的方式。
- 打包参数适配pool.map:
pool.map只认单个参数的函数,所以把需要的参数打包成元组,让函数自己解析就行。 - 强制关闭浏览器:用
try/finally保证不管爬取过程中出啥错,浏览器都会被关闭,不会留一堆僵尸进程拖慢电脑。 - 加进程入口判断:Windows系统下多进程必须有
if __name__ == "__main__",否则会无限创建子进程,直接崩给你看。
内容的提问来源于stack exchange,提问作者Austin Reed
相关产品推荐
相关产品推荐

