使用Pool.map()类型错误的多线程PhantomJS

时间:2018-09-09 14:08:07

标签: python multiprocessing

我的代码打印出错误 TypeError:执行时无法序列化'_io.TextIOWrapper'对象。 我的目标是使用硒并行化Ajax抓取,因为我不太了解如何直接抓取Ajax调用。 我的最终目标是将数字列表 a = [1,2,3,4] 替换为网址列表 a = [' url1','url2',...] 用于屏幕抓取(这只是“原型”代码)。 我会很欣赏该解决方案的简单而准确的解释,因为它不太擅长编程。谢谢。

from multiprocessing import Pool
from selenium import webdriver

def func(x):
    y=x[0]
    return y*y


if __name__=='__main__':
    a=[1,2,3,4]
    drivers=[webdriver.PhantomJS() for x in range(4)]
    c=zip(a,drivers)
    p=Pool(4)
    results=p.map(func,c)
    p.close()
    for result in results:
        print(result)

1 个答案:

答案 0 :(得分:0)

在不了解seleniumwebdriver的情况下,很明显它会打开TextIOWrapper对象。确切的原因,我不知道,但这可能是例如包装的文件索引或套接字。问题在于该对象无法序列化并在您的不同进程之间传递。

当前情况下最简单的解决方案是改为让每个进程实例化自己的driver并只是传递数据并将结果返回给主进程:

from multiprocessing import Pool
from selenium import webdriver

def func(x):
    driver = webdriver.PhantomJS() # To be used in current function (process)
    y = x
    return y*y

if __name__ == '__main__':
    a = [1,2,3,4]
    p = Pool(4)
    results = p.map(func, a)
    p.close()
    for result in results:
        print(result)

请注意,如果您想让driver保持活动状态以便以后执行更多操作,则此操作将无效。在这种情况下,您需要一个更精细的方案,在该方案中您需要提前设置流程(在创建initializer时使用Pool参数)。