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

前言

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

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

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

强调一下,

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

知识点

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

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

【Selenium】控制当前已经打开的 chrome浏览器窗口 【Selenium】控制当前已经打开的 chrome浏览器窗口(高级版) Python模块psutil:系统进程管理与Selenium效率提升的完美结合 Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

具体实现

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

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

初始化浏览器

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 硬件加速可以解决兼容性问题,提高稳定性。 作用:禁用Chrome 的GPU 硬件加速。 应用场景:与无头模式配合使用。 注意事项:禁用GPU 加速可能会影响浏览器性能,通常会增加图形网站的渲染时间。

示例代码

if __name__ == '__main__':

options = Options()

options.add_argument("--disable-gpu")

driver = init_driver(options=options)

代码汇总

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

代码释义:

检查特定的 Chrome 浏览器进程是否运行:通过 check_if_specific_chrome_running 函数,检查系统中是否有一个特定的 Chrome 浏览器进程在运行,这是通过匹配进程名和命令行参数完成的。 启动 Chrome 浏览器:如果没有发现指定的 Chrome 浏览器进程在运行,start_chrome 函数会启动一个新的 Chrome 浏览器实例,使用了一系列预定义的命令行参数。 使用 Selenium 连接到 Chrome 浏览器:通过 selenium_conn_browser 函数,使用 Selenium WebDriver 连接到指定端口的 Chrome 浏览器实例。这个函数还提供了选项来禁用 JavaScript 和设置页面加载策略。 打开特定网站进行测试:在 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~

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: