Selenium性能优化:一文带你快速上手!

举报
frica01 发表于 2023/12/31 18:49:50 2023/12/31
【摘要】 本文介绍了多种提升Selenium性能的技巧,从基本的无头模式到复杂的页面加载策略。这些优化方法不仅能够加速测试过程,还能提高测试的准确性和可靠性。

image.png

提升 Selenium 性能:实用优化技巧与最佳实践

前言

在自动化测试领域(做爬虫、自动化办公也不是不行😁😁),Selenium 是一个极为强大且广泛使用的工具。

学会使用工具是开始,学会优化该工具的使用才属于是真正的学会使用这个工具。面对日益复杂的网页结构和动态内容,仅仅掌握 Selenium 的基础操作已经过时啦!!!为了充分发挥 Selenium 的作用,必须深入了解并应用各种性能优化技巧。

本文将为大家展示一系列实用的 Selenium 性能优化技巧,从 无头模式显式等待时间 的设置,每一项都是为了提高自动化脚本的效率和稳定性。我们将探讨如何通过精细调整浏览器设置、减少不必要的资源加载以及合理设置等待策略,来优化测试流程和提升性能。无论你是 Selenium 的新手还是有经验的开发者,这些技巧都将为你的 Selenium 水平带来不少提升,并帮助你更高效地完成自动化任务。

强调一下,

  • 真正的性能瓶颈更多地在于网络延迟、页面渲染时间或脚本本身的效率。

知识点📖📖

模块 链接 作用
selenium https://www.selenium.dev/zh-cn/documentation/ 支持 web 浏览器自动化的一系列工具和库的综合项目

如果有看不懂的地方,可以结合我以前的文章一起看。

具体实现

下面,我分别从优势作用应用场景注意事项 为大家介绍以下的这些性能优化的操作。

这些优势可以根据具体的自动化任务和需求来选择性能优化选项,以提高任务执行效率和可靠性。

初始化浏览器

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager


def init_driver(options=None) -> webdriver.Chrome:
    """
    初始化浏览器驱动.

    Args:
        options(Options): chrome配置选项

    Returns:
        driver(WebDriver): 浏览器驱动对象

    """
    return webdriver.Chrome(
        service=ChromeService(ChromeDriverManager().install()),
        options=options
    )


显式等待时间

优势:确保任务在特定条件满足时执行,提高任务的稳定性和可靠性。
作用:适用于等待页面的特定条件满足,如元素可见或可点击。
应用场景:处理动态加载的页面内容。
注意事项:在需要等待特定条件满足时使用显式等待。设置合理的等待时间,以避免任务失败或效率低下。

示例代码

if __name__ == '__main__':
    driver = init_driver()
    wait = WebDriverWait(driver, 10)
    element = wait.until(EC.presence_of_element_located((By.ID, 'frica')))


无头模式

优势:减少内存占用和CPU消耗,提高性能,适合在后台运行自动化任务。
作用:运行Chrome 浏览器而不显示GUI界面。
应用场景:适用于不需要交互的界面测试。
注意事项:无头模式下无法可视化查看浏览器操作,需要注意页面的尺寸,以预防元素不可见。

示例代码

if __name__ == '__main__':
    options = Options()
    options.add_argument("--headless")
    driver = init_driver(options=options)
    driver.get('https://www.baidu.com')
    print(driver.title)
    # 百度一下,你就知道


无沙盒模式

优势:解决在某些环境中的权限问题,适用于对安全性要求不高的任务。
作用:禁用Chrome 的沙盒安全模式。
应用场景:在Docker等容器环境中运行。
注意事项:无沙盒模式可能降低安全性。在受信任的网站上使用此选项,不要在不信任的网站上执行代码。

示例代码

if __name__ == '__main__':
    options = Options()
    options.add_argument("--headless")
    driver = init_driver(options=options)


指定页面加载策略

优势:根据任务需求选择加载策略,可以提高页面加载速度或等待主要资源加载完成。
作用:定义Selenium 何时开始执行命令。
应用场景:加速测试或处理特殊页面
注意事项:根据任务需求选择适当的页面加载策略。

示例代码

  • none 表示不等待页面加载,
  • normal 表示等待页面加载完成,
  • eager 表示等待主要资源加载完成。
if __name__ == '__main__':
    options = Options()
    options.page_load_strategy = 'none'
    driver = init_driver(options=options)


指定浏览器配置文件

优势:保持个性化设置和登录状态。可以确保浏览器设置的一致性,适用于多个任务共享相同配置的情况。
作用:使用特定的Chrome 用户配置文件。
应用场景:持久化测试环境设置。
注意事项:指定配置文件可能有助于保持浏览器设置的一致性,确保配置文件存在且正确。

示例代码

if __name__ == '__main__':
    options = Options()
    # 替换成你本地的路径,
    options.add_argument(r"user-data-dir=F:\selenium\AutomationProfile")
    driver = init_driver(options=options)


禁止弹出拦截

优势:确保所有弹窗内容都能加载,确保任务顺利执行
作用:禁用Chrome 的弹出窗口拦截。
应用场景:测试包含弹出窗口的网页。
注意事项:禁用弹出拦截可能会导致弹出窗口干扰自动化任务。需要确保任务不受弹出窗口的影响。

示例代码

if __name__ == '__main__':
    options = Options()
    # 替换成你本地的路径,
    options.add_argument("--disable-popup-blocking")
    driver = init_driver(options=options)


禁用图片加载

优势:可以加快页面加载速度,减少网络流量消耗,适用于不依赖图片的任务。
作用:阻止网页中的图片加载。
应用场景:测试纯文本页面功能。
注意事项:禁用图片加载可能会加快页面加载速度,确保任务不依赖于图像元素。

示例代码

  • 1:允许加载所有图像。这是默认值,网页上的所有图像都会加载。
  • 2:禁止加载图像。浏览器不会加载网页上的任何图像。
  • 3:按照网页设置加载图像。这将遵循网页上的图像加载设置,如果网页未显式指定加载行为,则将使用默认行为。
if __name__ == '__main__':
    options = Options()
    # 方法一
    options.add_argument("--blink-settings=imagesEnabled=false")
    # 方法二
    prefs = {"profile.managed_default_content_settings.images": 2}
    options.add_experimental_option("prefs", prefs)
    driver = init_driver(options=options)


禁用JavaScript

使用 DevTools Protocol 来禁用 JavaScript

优势:禁用 JavaScript 可以降低网页的复杂性,提高加载速度,适用于不需要JavaScript 的任务。
作用:在页面加载中禁用JavaScript 执行。
应用场景:测试网页在无JavaScript 环境下的兼容性
注意事项:禁用JavaScript 会影响网页的交互性和动态内容加载。确保任务不需要JavaScript

示例代码

  • 这时候应该会发现,交互式元素(例如按钮、表单验证等)无法正常工作。
if __name__ == '__main__':
    options = Options()
    driver = init_driver(options=options)
    # 使用 DevTools Protocol 来禁用 JavaScript
    driver.execute_cdp_cmd("Emulation.setScriptExecutionDisabled", {"value": True})
    # 访问示例网站
    driver.get('https://frica.blog.csdn.net/?type=blog')


禁用插件扩展插件

一般来说,没有这个需要!
默认情况下 Selenium 不会加载浏览器中已安装的扩展;

如果需要在 Selenium中加载特定的扩展插件,你可以通过 Options 对浏览器的选项来指定扩展的路径或参数。
所以,如果不显式指定扩展或插件,Selenium 创建的浏览器会以默认配置启动,不会加载用户自定义的扩展或插件。

优势:禁用扩展可以提高浏览器性能,减少资源占用,适用于不需要扩展的任务。
作用:禁用Chrome 的所有扩展。
应用场景:保持测试环境的纯净性。
注意事项:无

示例代码

if __name__ == '__main__':
    options = Options()
    options.add_argument("--disable-extensions")
    driver = init_driver(options=options)


禁用GPU硬件加速

优势:在某些情况下,禁用 GPU 硬件加速可以解决兼容性问题,提高稳定性。
作用:禁用ChromeGPU 硬件加速。
应用场景:与无头模式配合使用。
注意事项:禁用GPU 加速可能会影响浏览器性能,通常会增加图形网站的渲染时间。

示例代码

if __name__ == '__main__':
    options = Options()
    options.add_argument("--disable-gpu")
    driver = init_driver(options=options)

代码汇总

结合以前文章的代码来对本文进行总结,nice!!!

代码释义:

  1. 检查特定的 Chrome 浏览器进程是否运行:通过 check_if_specific_chrome_running 函数,检查系统中是否有一个特定的 Chrome 浏览器进程在运行,这是通过匹配进程名和命令行参数完成的。

  2. 启动 Chrome 浏览器:如果没有发现指定的 Chrome 浏览器进程在运行,start_chrome 函数会启动一个新的 Chrome 浏览器实例,使用了一系列预定义的命令行参数。

  3. 使用 Selenium 连接到 Chrome 浏览器:通过 selenium_conn_browser 函数,使用 Selenium WebDriver 连接到指定端口的 Chrome 浏览器实例。这个函数还提供了选项来禁用 JavaScript 和设置页面加载策略。

  4. 打开特定网站进行测试:在 selenium_conn_browser 函数中,代码打开了指定的网址(例如 CSDN 博客页面)并等待一段时间,以便进行进一步的操作或测试。

总体来说,这个脚本用于自动化地控制和与 Chrome 浏览器进行交互,适用于网页自动化测试或类似的场景。

启动浏览器

不建议在命令中实现无头模式,因为这会导致 Selenium连接失败,具体看这篇文章!
Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

# -*- coding: utf-8 -*-
# @Author : Frica01
# @Time   : 2023-12-03 21:27
# @Name   : demo.py

import subprocess
import time
from typing import List

import psutil
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


def check_if_specific_chrome_running(process_name, cmdline=None) -> bool:
    """
    检查是否有包含指定名称的进程正在运行。

    Args:
        process_name(str): 要检查的进程名
        cmdline(List[str]): 要检查的命令行参数。默认为None。

    Returns:
        bool: 如果找到匹配的进程则返回True,否则返回False。
    """
    # 遍历所有正在运行的进程
    for proc in psutil.process_iter():
        try:
            # 检查进程名是否包含给定的名称字符串
            if process_name.lower() in proc.name().lower():
                # 获取进程详细信息列表
                p_info = proc.as_dict(attrs=['pid', 'name', 'cmdline'])
                # 如果提供了cmdline,检查它是否在进程的cmdline中
                if cmdline:
                    if all(cmd in p_info['cmdline'] for cmd in cmdline):
                        return True
                # 如果没有提供cmdline,返回True,因为进程名匹配
                else:
                    return True
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    return False


def start_chrome(browser_path, commands_list=None) -> None:
    """
    启动浏览器。

    Args:
        browser_path(str): 浏览器安装的路径
        commands_list(List[str]): 启动浏览器的命令行参数,默认为None

    Returns:
        None
    """
    commands = [browser_path]
    commands.extend(commands_list)
    # 启动浏览器
    subprocess.Popen(commands)



if __name__ == '__main__':
    # 设置浏览器的路径和启动参数
    path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
    port = 9527
    cmd_map = {
        '指定浏览器配置': r'--user-data-dir=F:\selenium',
        '指定远程调试端口': '--remote-debugging-port={}'.format(port),
        # '无头模式': '--headless', # 不建议在命令中实现无头模式,因为这会导致Selenium连接失败
        '无沙盒模式': '--no-sandbox',
        # '指定页面加载策略': '--no-sandbox',
        '禁用弹出拦': '--disable-popup-blocking',
        '禁用图片加载': '--blink-settings=imagesEnabled=false',
        '禁用GPU硬件加速': '--disable-gpu',
        # '禁用js': True,
    }
    if not check_if_specific_chrome_running('chrome', cmdline=list(cmd_map.values())):
        # 打开浏览器
        start_chrome(path, commands_list=list(cmd_map.values()))

连接浏览器

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager


def init_chrome_driver(options=None) -> webdriver.Chrome:
    """
    初始化浏览器驱动.

    Args:
        options(Options): chrome配置选项

    Returns:
        driver(WebDriver): 浏览器驱动对象

    """
    return webdriver.Chrome(
        service=ChromeService(ChromeDriverManager().install()),
        options=options
    )


def selenium_conn_browser(port, disable_js=False, page_load_strategy=False):
    options = Options()
    # 设置页面加载策略
    if page_load_strategy:
        options.page_load_strategy = 'none'
    options.add_experimental_option("debuggerAddress", f"127.0.0.1:{port}")
    driver = init_chrome_driver(options=options)
    # 使用 DevTools Protocol 来禁用 JavaScript
    if disable_js:
        driver.execute_cdp_cmd("Emulation.setScriptExecutionDisabled", {"value": True})
    # 访问示例网站
    driver.get('https://frica.blog.csdn.net/?type=blog')
    time.sleep(20)


if __name__ == '__main__':
    # se连接浏览器
    selenium_conn_browser()

总结

通过本文,我们了解了多种提升 Selenium 性能的技巧,从基本的无头模式到复杂的页面加载策略。这些优化方法不仅能够加速测试过程,还能提高测试的准确性和可靠性。实践表明,正确地应用这些技巧可以显著提高自动化测试的效率。鼓励读者在自己的项目中尝试这些方法,并根据具体情况进行调整,以发挥 Selenium 的最大作用。

总体而言,这篇文章是一份非常全面和实用的 Selenium 性能优化指南。选择性能优化选项时,我们需要根据具体任务的要求和网站的特性来选择对应的选项。在实际使用中,进行充分的测试和调试以确保任务的稳定性和性能提升。

后话

本次分享到此结束,

see you~🎈🎈

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。