Python Диспетчер многопроцессорной обработки - ошибка с именем списка? - PullRequest
0 голосов
/ 09 февраля 2020

Я пытаюсь использовать общий список, который будет обновлять извлеченную информацию из Selenium, чтобы впоследствии я мог экспортировать эту информацию или использовать ее по своему выбору. По какой-то причине он выдает мне эту ошибку: NameError: имя 'scrapedinfo' не определено ...

Это действительно странно для меня, потому что я объявил список глобальным И я использовал 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://stackoverflow.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()

1 Ответ

1 голос
/ 09 февраля 2020

В Windows многопроцессорная обработка запускает новый процесс python, а затем пытается выбрать / удалить ограниченное представление родительского состояния для дочернего элемента. Глобальные переменные, которые не передаются в вызове 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://stackoverflow.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 передает возвращаемое значение работника обратно в родительский процесс (и обрабатывает разбиение на фрагменты). Таким образом, вы можете сделать:

from multiprocessing import Pool, Manager

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

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

if __name__=="__main__":
    multip()

И избежать дополнительной обработки неуклюжего прокси-списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...