'TypeError(“无法腌制生成器对象”):Concurrent.future与Asyncio

时间:2019-12-17 16:18:49

标签: python concurrency python-asyncio concurrent.futures

我想从python列表中的每个对象中并发执行相同的实例方法。

我创建了一个DataPipe类,该类下载页面并将结果存储在数组中。然后,当我完成下载特定域感兴趣的链接时,我生成了这些页面,然后从页面中生成了对应的项。

该代码可以正常工作,现在,我想同时从多个域下载。

class DownloadCommand(Command):

    def __init__(self, domain):
        self.domain = domain
        self.request_config = {'headers': self.domain.get_header(), 'proxy': self.domain.get_proxy()}
        self.data_pipe = DataPipe(command=self)

    def execute(self):
        # try:
        for brand, start_urls in self.domain.start_url.items():
            for start_url in start_urls:
                # yield from self.data_pipe.get_item_divs(brand, start_url)
                yield from self.data_pipe.get_item_divs(brand, start_url)`

目前,我正在按顺序执行此操作。

def scrape(self):
   for domain in self.get_initial_domain_list():
        yield from self.fetch_from_dom(domain)

def fetch_from_dom(self, domain):
    self.set_current_domain(domain)
    for start_url_values, brand, start_url in domain.command.execute():
        for items in start_url_values:
            yield [self.get_item_value(item_div) for item_div in items]

我尝试使用multiprocessing.pool.Pool对这个应用程序进行多线程处理,但是它不适用于实例方法。然后,当我使用pathos.multiprocessing import ProcessingPool时返回错误:

 multiprocess.pool.MaybeEncodingError: Error sending result: '[<generator object fetch_from_dom at 0x7fa984814af0>]'. Reason: 'TypeError("can't pickle generator objects",)'

我想切换到asyncioconcurrent.futures,但我不确定如果实际上可以在python中进行,那么哪种方法最好做我想做的呢?从列表中的对象执行实例方法)。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

不能将硒与python多重处理一起使用,从而导致克隆内存。您可以尝试避免使用线程更简单。但这是我的多处理解决方案

注意:自我是我的驱动程序,因为我已经在Selenium上实现了自定义类

#Exit function
def cleanup(self):
    print("++cleanup()++")
    try:
        try:
            self.close()
        except Exception as e:
            #print("except cleanup - 2 - self.close() -> %s" %e)
            pass

        try:
            self.quit()
        except Exception as e:
            #print("except cleanup - 3 - self.quit() -> %s" %e)
            pass


        try:
            self.dispose()
            #print("Fake disabled dispose()")
        except Exception as e:
            #print("except cleanup - 4 - self.dispose() -> %s" %e)
            pass


        try:
            self.service.process.send_signal(signal.SIGTERM)
        except Exception as e:
            #print("except cleanup - 1 - self.service.process.send_signal(signal.SIGTERM) -> %s" %e)
            pass

    except Exception as e:
        print("Except - CLEANUP -> %s" %e)
        #print(str(e))
        pass

使用脚本代码

#Before start threads
browser.cleanup()
del browser


#Now start multiprocessing and instance browser on each subprocess