Python 多处理管理器 - 列表名称错误?

Python Multiprocessing Manager - List Name Error?

我正在尝试使用一个共享列表来更新从 Selenium 中抓取的信息,以便我以后可以导出此信息或按我选择的方式使用它。出于某种原因,它给了我这个错误: NameError: 名称 'scrapedinfo' 未定义...

这对我来说真的很奇怪,因为我将列表声明为 Global 并且我使用 multiprocessing.Manager() 来创建列表。我已经多次仔细检查我的代码,这不是区分大小写的错误。我还尝试将列表作为变量传递给函数,但这会产生其他问题并且没有用。任何帮助是极大的赞赏!

from selenium import webdriver
from multiprocessing import Pool

def browser():  
    driver = webdriver.Chrome()
    return driver

def test_func(link):
    driver = browser()
    driver.get(link)

def scrape_stuff(driver):

    #Scrape things
    scrapedinfo.append(#Scraped Stuff)

def multip():
    manager = Manager()

    #Declare list here

    global scrapedinfo
    scrapedinfo = manager.list()

    links = ["https://whosebug.com/", "https://signup.microsoft.com/", "www.example.com"]
    chunks = [links[i::3] for i in range(3)]
    pool = Pool(processes=3)
    pool.map(test_func, chunks)
    print(scrapedinfo)

multip()

在 Windows 中,多处理执行一个新的 python 进程,然后尝试 pickle/unpickle 子进程的父状态的有限视图。不包括未在 map 调用中传递的全局变量。 scrapedinfo 未在子项中创建,您收到错误。

一种解决方案是在地图调用中传递 scrapedinfo。举个简单的例子,

from multiprocessing import Pool, Manager

def test_func(param):
    scrapedinfo, link = param
    scrapedinfo.append("i scraped stuff from " + str(link))

def multip():
    manager = Manager()

    global scrapedinfo
    scrapedinfo = manager.list()

    links = ["https://whosebug.com/", "https://signup.microsoft.com/", "www.example.com"]
    chunks = [links[i::3] for i in range(3)]
    pool = Pool(processes=3)
    pool.map(test_func, list((scrapedinfo, chunk) for chunk in chunks))
    print(scrapedinfo)

if __name__=="__main__":
    multip()

但是您与经理一起做的工作比您需要做的更多。 map 将 worker 的 return 值传递回父进程(并处理分块)。所以你可以这样做:

from multiprocessing import Pool, Manager

def test_func(link):
    return "i scraped stuff from " + link

def multip():
    links = ["https://whosebug.com/", "https://signup.microsoft.com/", "www.example.com"]
    pool = Pool(processes=3)
    scrapedinfo = pool.map(test_func, links)
    print(scrapedinfo)

if __name__=="__main__":
    multip()

并避免笨拙的列表代理的额外处理。