concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threading和multiprocessing的进一步抽象,对编写线程池/进程池提供了直接的支持。
问题:有10万条url需要爬取,如何以比较简单的方式实现多进程/多线程爬取?
1 | import logging |
此处,id_gen()函数是一个生成器,模拟10万条url。
map(fn, *iterables, timeout=None),第一个参数fn是线程执行的函数;第二个参数接受一个可迭代对象;第三个参数timeout跟wait()的timeout一样,但由于map是返回线程执行的结果,如果timeout小于线程执行时间会抛异常TimeoutError。
ProcessPoolExecutor在使用上和ThreadPoolExecutor大致是一样的,它们在futures中的方法也是相同的,但是对于map()方法ProcessPoolExecutor会多一个参数chunksize(ThreadPoolExecutor中这个参数没有任何作用),chunksize将迭代对象切成块,将其作为分开的任务提交给pool,对于很大的iterables,设置较大chunksize可以提高性能。
submit
1 | from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor |
若test有多个参数,在submit里面也直接写多个参数即可;如test(a, b, c)
,executor.submit(test, a, b, c)