selenium多进程分摊爬虫任务基础

selenium多进程分摊爬虫任务基础

1. 背景

  • 现在有这样一个需求:爬取淘宝商品信息,具体的流程是,在搜索栏输入关键字,然后爬取搜索结果列表中的商品信息。
  • 分析这个需求会发现具有如下特点:
    • 第一,淘宝请求url具有一定的反爬措施,构造起来困难 ——> 应对这种问题的方案就是采用selenium浏览器渲染技术去爬取。
    • 第二,实践发现,目前淘宝对这个爬取频率并没有做很大的限制。也就是说,可以在selenium的基础上,加上多进程并发的方式,并行爬取数据,加快爬取速度。

2. 环境

  • python 3.6.1
  • 系统:win7
  • IDE:pycharm
  • selenium 3.7.0

3. 多进程任务分摊

  • 基本思路:
    • 第一,开多个进程,并行运行多个chrome浏览器。
    • 第二,将所有的关键字放入同一个queue中,其他进程从中获取关键字,进行搜索数据。
import configure
import multiprocessing
import time

# 由mark标记是哪个进程执行的动作
def getkeyWordFunc(queue, lock, mark):
    while not queue.empty():
        # def get(self, block=True, timeout=None):
        keyWord = queue.get()

        # 加锁,是为了防止散乱的打印。 保护一些临界状态
        # 多个进程运行的状态下,如果同一时刻都调用到print,那么显示的打印结果将会混乱
        lock.acquire()
        print(f"keyWord = {keyWord}, markProcess = {mark}")
        lock.release()
        time.sleep(1)

if __name__ == '__main__':
    lock = multiprocessing.Lock()       # 进程锁
    queue = multiprocessing.Queue(150)  # 队列,用于存放所有的初始关键字

    for keyWord, keyWordValue in configure.keySearchWords.items():
        print(f"keyWord = {keyWord}")
        # 如果queue定的太小,剩下的放不进去,程序就会block住,等待队列有空余空间
        # def put(self, obj, block=True, timeout=None):
        queue.put(keyWord)
    print(f"queueBefore = {queue}")

    getKeyProcessLst = []
    # 生成两个进程,并启动
    for i in range(2):
        process = multiprocessing.Process(target = getkeyWordFunc, args = (queue, lock, i))
        process.start()
        getKeyProcessLst.append(process)

    # 守护线程
    # join 等待线程终止,如果不使用join方法对每个线程做等待终止,那么线程在运行过程中,可能会去执行最后的打印
    # 如果没有join,父进程就不会阻塞,启动子进程之后,父进程就直接执行最后的打印了
    for p in getKeyProcessLst:
        p.join()

    print(f"queueAfter = {queue}")
    queue.close()
    print(f"all queue used.")
  • 运行结果:可以看到关键字被分摊到两个进程中去了
queueBefore = <multiprocessing.queues.Queue object at 0x0000000002277F60>
keyWord = 头巾, markProcess = 0
keyWord = 上衣, markProcess = 1
keyWord = 铁碗, markProcess = 0
keyWord = 玩具, markProcess = 1
keyWord = 苹果, markProcess = 0
keyWord = 床单, markProcess = 1
keyWord = 石榴, markProcess = 0
queueAfter = <multiprocessing.queues.Queue object at 0x0000000002277F60>
all queue used.
相关文章
相关标签/搜索