【问题标题】:Python Multiprocessing - TypeError: Pickling an AuthenticationString object is disallowed for security reasonsPython 多处理 - 类型错误:出于安全原因,不允许腌制 AuthenticationString 对象
【发布时间】:2018-02-15 05:40:03
【问题描述】:

我遇到以下问题。我想实现一个网络爬虫,到目前为止这工作但它太慢了,我试图使用多处理来获取 URL。 不幸的是,我在这个领域不是很有经验。 经过一些阅读,我认为最简单的方法是使用 multiprocessing.pool 中的 map 方法。

但我经常收到以下错误:

TypeError: Pickling an AuthenticationString object is disallowed for security reasons

我发现很少有相同错误的案例,很遗憾它们没有帮助我。

我创建了一个可以重现错误的代码的剥离版本:

import multiprocessing

class TestCrawler:
    def __init__(self):
        self.m = multiprocessing.Manager()
        self.queue = self.m.Queue()
        for i in range(50):
            self.queue.put(str(i))
        self.pool = multiprocessing.Pool(6)



    def mainloop(self):
        self.process_next_url(self.queue)

        while True:
            self.pool.map(self.process_next_url, (self.queue,))                

    def process_next_url(self, queue):
        url = queue.get()
        print(url)


c = TestCrawler()
c.mainloop()

如果有任何帮助或建议,我将不胜感激!

【问题讨论】:

    标签: python python-3.x queue multiprocessing python-multiprocessing


    【解决方案1】:

    问题:但我经常收到以下错误:

    您得到的错误具有误导性,原因是

    self.queue = self.m.Queue()
    

    Queue 实例移到class TestCrawler 之外。
    这会导致另一个错误:

    NotImplementedError:池对象不能在进程之间传递或腌制

    原因是:

    self.pool = multiprocessing.Pool(6)
    

    这两个错误都表明pickle 找不到class Members

    注意:无限循环!
    您关注的while 循环导致无限循环! 这将超载您的系统!
    此外,您的 pool.map(... 仅以 一个 Processone 任务开始!

        while True:
            self.pool.map(self.process_next_url, (self.queue,)) 
    

    我建议阅读The Examples that demonstrates the use of a pool


    更改如下:

    class TestCrawler:
        def __init__(self, tasks):
            # Assign the Global task to class member
            self.queue = tasks
            for i in range(50):
                self.queue.put(str(i))
    
        def mainloop(self):
            # Instantiate the pool local
            pool = mp.Pool(6)
            for n in range(50):
                # .map requires a Parameter pass None
                pool.map(self.process_next_url, (None,))
    
        # None is passed
        def process_next_url(self, dummy):
            url = self.queue.get()
            print(url)
    
    if __name__ == "__main__":
      # Create the Queue as Global
      tasks = mp.Manager().Queue()
      # Pass the Queue to your class TestCrawler
      c = TestCrawler(tasks)
      c.mainloop()
    

    本例启动5个进程,每个进程处理10个Tasks(urls):

    class TestCrawler2:
        def __init__(self, tasks):
            self.tasks = tasks
    
        def start(self):
            pool = mp.Pool(5)
            pool.map(self.process_url, self.tasks)
    
        def process_url(self, url):
            print('self.process_url({})'.format(url))
    
    if __name__ == "__main__":
        tasks = ['url{}'.format(n) for n in range(50)]
        TestCrawler2(tasks).start()
    

    用 Python 测试:3.4.2

    【讨论】:

    • 非常感谢您的回答!它适用于简短的示例,但是当我以这种方式在程序中更改它时,我仍然遇到同样的问题。你能不能给我一些解释酸洗的资源?在查找此内容时,我主要会收到有关 pickle 模块的文本。
    • @blue: Edit 您的问题并显示您用于 pool.map(...args=,我假设您仍在尝试传递 muliprocessing 对象不可能!
    • 此代码仅适用于 'map' 方法,不适用于 apply_async
    猜你喜欢
    • 2018-06-18
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2021-11-10
    • 2020-09-22
    • 2022-01-02
    相关资源
    最近更新 更多