【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合

这篇具有很好参考价值的文章主要介绍了【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合

前言

使用Selenium 创建多个浏览器,这在自动化操作中非常常见。

而在Python中,使用 Selenium + threading Selenium + ThreadPoolExecutor 都是很好的实现方法。

应用场景:

  • 创建多个浏览器用于测试或者数据采集;
  • 使用Selenium 控制本地安装的 chrome浏览器 去做一些操作

文章提供了 Selenium + threading Selenium + ThreadPoolExecutor 结合的代码模板,拿来即用。



知识点📖📖

作用 链接
threading用于实现多线程 https://docs.python.org/zh-cn/3/library/threading.html
concurrent.futures.ThreadPoolExecutor 使用线程池来异步执行调用 https://docs.python.org/zh-cn/3/library/concurrent.futures.html

上面两个都是 Python 内置模块,无需手动安装~


导入模块

import threading
from concurrent.futures import ThreadPoolExecutor, as_completed



多线程还是线程池?

Selenium中,使用 多线程 或者是 线程池,差别并不大。主要都是网络I/O的操作。

在使用 ThreadPoolExecutor 的情况下,任务将被分配到不同的线程中执行,从而提高并发处理能力。与使用 threading 模块相比,使用 ThreadPoolExecutor 有以下优势:

  1. 更高的并发处理能力:线程池 可以动态地调整线程数量,以适应任务的数量和处理要求,从而提高并发处理能力。
  2. 更好的性能:线程池 可以根据任务的类型和大小动态地调整线程数量,从而提高性能和效率。

总之,使用 线程池 可以提高并发处理能力,更易于管理,并且可以提供更好的性能和效率。

但是选择多线程,效果也不差。

所以使用哪个都不必纠结,哪个代码量更少就选哪个自然是最好的。


多个浏览器✨

Selenium自动化中需要多个浏览器,属于是非常常见的操作了。
不管是用于自动化测试、还是爬虫数据采集,这都是个可行的方法。

这里示例的代码中,线程池的运行时候只有 多线程 的一半!!!

多线程与 多 浏览器🧨

这份代码的应用场景会广一些,后续复用修改一下 browser_thread 函数的逻辑就可以了。

这里模拟相对复杂的操作,在创建的浏览器中新打开一个标签页,用于访问指定的网站。
然后切换到新打开的标签页,进行截图。



代码释义:

  • 定义一个名为 start_browser 的函数,用于创建 webdriver.Chrome 对象。
  • 定义一个名为 browser_thread 的函数,接受一个 webdriver.Chrome 对象和一个整数作为参数,用于打开指定网页并截图。 切换到最后一个窗口,然后截图。
  • main函数创建了5个浏览器,5个线程,执行上面的操作,然后等待所有线程执行完毕。
# -*- coding: utf-8 -*-
# Name:         multi_thread.py
# Author:       小菜
# Date:         2023/6/1 20:00
# Description:


import threading
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService

from webdriver_manager.chrome import ChromeDriverManager


def start_browser():
    service = ChromeService(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service)
    return driver


def browser_thread(driver: webdriver.Chrome, idx: int):
    url_list = ['https://www.csdn.net/', 'https://www.baidu.com',
                'https://music.163.com/', 'https://y.qq.com/', 'https://cn.vuejs.org/']

    try:
        driver.execute_script(f"window.open('{url_list[idx]}')")
        driver.switch_to.window(driver.window_handles[-1])
        driver.save_screenshot(f'{idx}.png')
        return True
    except Exception:
        return False


def main():
    for idx in range(5):
        driver = start_browser()
        threading.Thread(target=browser_thread, args=(driver, idx)).start()

    # 等待所有线程执行完毕
    for thread in threading.enumerate():
        if thread is not threading.current_thread():
            thread.join()


if __name__ == "__main__":
    main()

运行结果

  • 运行时长在9.28秒(速度与网络环境有很大关系,木桶效应,取决于最后运行完成的浏览器
  • 看到程序运行完成后,多出了5张截图。

【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合

线程池与 多 浏览器🎍

这份代码与 多线程与 多浏览器 的操作基本一致。速度上却比多线程节省了一半。

# -*- coding: utf-8 -*-
# Name:         demo2.py
# Author:       小菜
# Date:         2023/6/1 20:00
# Description:


from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from concurrent.futures import ThreadPoolExecutor, as_completed

MAX_WORKERS = 5
service = ChromeService(ChromeDriverManager().install())


def start_browser():
    driver = webdriver.Chrome(service=service)
    return driver


def browser_task(driver: webdriver.Chrome, idx: int):
    url_list = ['https://www.csdn.net/', 'https://www.baidu.com',
                'https://music.163.com/', 'https://y.qq.com/', 'https://cn.vuejs.org/']

    try:
        driver.execute_script(f"window.open('{url_list[idx]}')")
        driver.switch_to.window(driver.window_handles[-1])
        driver.save_screenshot(f'{idx}.png')
        return True
    except Exception:
        return False


def main():
    executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)
    ths = list()
    for idx in range(5):
        driver = start_browser()
        th = executor.submit(browser_task, driver, idx=idx)
        ths.append(th)

    # 获取结果
    for future in as_completed(ths):
        print(future.result())


if __name__ == "__main__":
    main()

运行结果

  • 运行时长在4.5秒(运行效果图不是很匹配,但确实是比多线程快很多。
  • 看到程序运行完成后,多出了5张截图。【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合

多个标签页

这个的应用场景有点意思。

这里的操作与上面的 多个浏览器其实是差不多的。
区别在于:上面打开多个浏览器,这里打开多个标签页。

所以这个需要考量一个问题:资源争夺。与是这里用上了 threading.Lock 锁,用以保护资源线程安全。

多线程与 多 标签页🎃

代码释义:

  • 与上面差不多,不解释了。
# -*- coding: utf-8 -*-
# Name:         demo2.py
# Author:       小菜
# Date:         2023/6/1 20:00
# Description:

import threading
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService

from webdriver_manager.chrome import ChromeDriverManager

service = ChromeService(ChromeDriverManager().install())
lock = threading.Lock()


def start_browser():
    driver = webdriver.Chrome(service=service)
    return driver


def browser_thread(driver: webdriver.Chrome, idx: int):
    url_list = ['https://www.csdn.net/', 'https://www.baidu.com',
                'https://music.163.com/', 'https://y.qq.com/', 'https://cn.vuejs.org/']
    try:
        lock.acquire()
        driver.execute_script(f"window.open('{url_list[idx]}')")
        driver.switch_to.window(driver.window_handles[idx + 1])
        driver.save_screenshot(f'{idx}.png')
        return True
    except Exception:
        return False
    finally:
        lock.release()


def main():
    driver = start_browser()
    for idx in range(5):
        threading.Thread(target=browser_thread, args=(driver, idx)).start()

    # 等待所有线程执行完毕
    for thread in threading.enumerate():
        if thread is not threading.current_thread():
            thread.join()


if __name__ == "__main__":
    main()

运行结果

【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合

线程池与 多 标签页👀

这里不展示运行结果了,因为效果与 多线程与 多 标签页 一致。

# -*- coding: utf-8 -*-
# Name:         thread_pool.py
# Author:       小菜
# Date:         2023/6/1 20:00
# Description:

import time
import threading

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from concurrent.futures import ThreadPoolExecutor, as_completed

MAX_WORKERS = 5
service = ChromeService(ChromeDriverManager().install())
lock = threading.Lock()


def start_browser():
    driver = webdriver.Chrome(service=service)
    return driver


def browser_task(driver: webdriver.Chrome, idx: int):
    url_list = ['https://www.csdn.net/', 'https://www.baidu.com',
                'https://music.163.com/', 'https://y.qq.com/', 'https://cn.vuejs.org/']

    try:
        lock.acquire()
        driver.execute_script(f"window.open('{url_list[idx]}')")
        driver.switch_to.window(driver.window_handles[idx + 1])
        driver.save_screenshot(f'{idx}.png')
        return True
    except Exception:
        return False
    finally:
        lock.release()


def main():
    driver = start_browser()
    executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)
    ths = list()
    for idx in range(5):
        th = executor.submit(browser_task, driver, idx=idx)
        ths.append(th)

    # 获取结果
    for future in as_completed(ths):
        print(future.result())


if __name__ == "__main__":
    st = time.time()
    main()
    et = time.time()
    print(et - st)

总结⚡⚡

本文章介绍了 Selenium + threading Selenium + ThreadPoolExecutor 来创建多个浏览器或多个标签页的操作。

文中示例的代码比较简单,所以 线程池多线程 运行的更加快。
但在实际的使用过程中,可以根据自己的喜好去选择 线程池 还是 多线程

后话

本次分享到此结束,

see you~🐱‍🏍🐱‍🏍文章来源地址https://www.toymoban.com/news/detail-495221.html

到了这里,关于【Selenium】提高测试&爬虫效率:Selenium与多线程的完美结合的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 利用生成式AI的产研流程:创新与效率的完美结合

    生成式AI(Generative AI)是一类人工智能技术,旨在生成新的、原创的数据、图像、音频、视频或其他形式的内容。它通过机器学习算法来学习和模拟现实世界中的数据分布,然后使用这些模型来生成新的、具有相似特征的数据。比如,在软件开发领域,生成式AI可以自动化代

    2024年02月05日
    浏览(45)
  • 利用优化算法提高爬虫任务调度效率

    在大规模数据采集的场景中,高效的任务调度是关键之一。通过利用优化算法,我们可以提高爬虫任务的调度效率,加快数据采集速度,并有效利用资源。本文将为您介绍如何利用优化算法来优化爬虫任务调度,实现高效的批量采集。 一、任务调度优化的重要性 在批量采集

    2024年02月09日
    浏览(32)
  • 工业厂房地面混凝土破损快速修复案例:安全与效率的完美结合

    引言 在工业领域中,厂房地面的完好性直接关系到生产线的稳定运行和工人的作业安全。然而,随着时间的推移,地面混凝土往往会出现破损、开裂等问题,给企业的生产带来诸多不便。因此,选择一家专业、高效的混凝土修补公司显得尤为重要。在众多修补公司中,清兆混

    2024年04月17日
    浏览(28)
  • 跨境电商与隐擎fox指纹浏览器:保障安全与效率的完美结合

          随着全球化的发展,跨境电商已成为各国贸易的重要组成部分。然而,随之而来的风险和挑战也日益增多,其中之一就是关联浏览器和多开浏览器可能带来的安全隐患。为了确保跨境电商的顺利运营和数据安全,隐擎fox指纹浏览器作为一种防关联浏览器和多开浏览器的

    2024年02月14日
    浏览(45)
  • 使用多线程或异步技术提高图片抓取效率

    图片抓取是爬虫技术中常见的需求,但是图片抓取的效率受到很多因素的影响,比如网速、网站反爬机制、图片数量和大小等。本文将介绍如何使用多线程或异步技术来提高图片抓取的效率,以及如何使用爬虫代理IP来避免被网站封禁。 多线程和异步技术都是利用计算机的并

    2024年02月09日
    浏览(31)
  • Java并发(二)----初次使用多线程并行提高效率

    并行代表充分利用多核 cpu 的优势,提高运行效率。 想象下面的场景,执行 3 个计算,最后将计算结果汇总。 如果是串行执行,那么总共花费的时间是 10 + 11 + 9 + 1 = 31ms 但如果是四核 cpu,各个核心分别使用线程 1 执行计算 1,线程 2 执行计算 2,线程 3 执行计算 3,那么 3 个

    2023年04月13日
    浏览(62)
  • 软件测试/测试开发丨Selenium 网页frame与多窗口处理

    本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27048 点击某些链接,会重新打开⼀个窗⼜,对于这种情况,想在新页⾯上操作,就 得先切换窗⼜了。 获取窗⼜的唯⼀标识⽤句柄表⽰,所以只需要切换句柄,就可以在多个页⾯灵 活操作了 先获

    2024年02月10日
    浏览(43)
  • 【PyQt5实现多线程更新UI】- 提高程序效率,优化用户体验

    【PyQt5实现多线程更新UI】- 提高程序效率,优化用户体验 在PyQt5应用程序的开发中,当程序需要处理大量数据或进行复杂的计算时,如果仅使用主线程,会导致GUI界面失去响应,用户体验较差。为了解决这个问题,通常需要使用多线程技术。 而在使用多线程时,往往需要更新

    2024年02月07日
    浏览(24)
  • 计算机视觉---flask框架封装目标检测,应用线程提高程序运行效率

    1.前言 上一篇文章flask部署 目标检测算法中讲到可以将检测算法封装到flask框架中进行web端展示,但在实际应用中发现一些问题并进行了解决,在本文中进行补充。 2.利用线程,提高flask程序运行效率 flask web端访问时,每次都会从头加载程序,导致每次访问页面刷新率很低或

    2024年02月16日
    浏览(32)
  • Python爬虫的应用场景与技术难点:如何提高数据抓取的效率与准确性

    作为专业爬虫程序员,我们在数据抓取过程中常常面临效率低下和准确性不高的问题。但不用担心!本文将与大家分享Python爬虫的应用场景与技术难点,并提供一些实际操作价值的解决方案。让我们一起来探索如何提高数据抓取的效率与准确性吧! 爬虫应用场景: 爬虫在各

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包