在使用 SeleniumBase 结合 Undetected chromeDriver (uc=True) 进行多线程处理时,可能会遇到页面加载失败的问题。这通常是由于多个线程同时使用代理,导致代理配置冲突所致。本文将介绍如何通过设置 multi_proxy=True 参数来解决代理冲突,并强调使用 pytest-xdist 进行多线程测试是 SeleniumBase 官方支持的方式。同时,也会讨论在不使用 pytest-xdist 的情况下进行多线程处理的注意事项。
解决代理冲突:multi_proxy=True
当使用 SeleniumBase 设置代理时,它会创建一个包含代理凭据的 zip 文件,并将其作为扩展加载到 Chrome 中。默认情况下,SeleniumBase 假设只使用一个代理,因此会覆盖现有的 zip 文件。当需要同时使用多个代理时,需要设置 multi_proxy=True 参数。这个参数会为每个使用代理的测试创建一个具有唯一名称的 zip 文件,从而避免代理冲突。
以下是一个示例代码,展示了如何使用 multi_proxy=True 参数:
from parameterized import parameterized from seleniumbase import BaseCase BaseCase.main(__name__, __file__, "-n3") class ProxyTests(BaseCase): @parameterized.expand( [ ["user1:pass1@host1:port1"], ["user2:pass2@host2:port2"], ["user3:pass3@host3:port3"], ] ) def test_multiple_proxies(self, proxy_string): self.get_new_driver( undetectable=True, proxy=proxy_string, multi_proxy=True ) self.driver.get("https://browserleaks.com/webrtc") self.sleep(30)
在这个例子中,get_new_driver 方法被调用,并设置了 undetectable=True,proxy=proxy_string 和 multi_proxy=True。multi_proxy=True 确保了每个测试都使用一个唯一的代理配置,从而避免了冲突。
注意事项:
- proxy_string 应该包含用户名、密码、主机和端口信息,格式为 user:pass@host:port。
- undetectable=True 启用 Undetected ChromeDriver,可以绕过一些反爬虫机制。
SeleniumBase 官方支持的多线程方式:pytest-xdist
SeleniumBase 官方支持使用 pytest-xdist 进行多线程测试。pytest-xdist 是一个 pytest 插件,允许将测试用例分发到多个 CPU 或机器上并行执行。SeleniumBase 的内置线程锁专门为通过 pytest 进行多线程处理而设计。
使用 pytest-xdist 的优势:
- 简单易用: 只需要安装 pytest-xdist 插件,并在运行 pytest 时添加 -n 参数即可启用多线程。例如,pytest -n 3 将使用 3 个线程并行执行测试。
- 线程安全: SeleniumBase 的内置线程锁可以确保在多线程环境下正确地管理资源。
- 官方支持: SeleniumBase 团队对 pytest-xdist 提供了全面的支持和维护。
不使用 pytest-xdist 的多线程处理
理论上,可以在不使用 pytest-xdist 的情况下进行多线程处理,但需要确保同一时间只启动一个 Chrome 浏览器。一旦浏览器启动,就可以同时运行多个实例。
注意事项:
- 需要手动管理线程锁,以避免资源冲突。
- 需要确保每个线程都有自己的独立环境和配置。
- 这种方式的复杂性较高,容易出错,建议尽可能使用 pytest-xdist。
总结
在使用 SeleniumBase 进行多线程处理时,如果遇到页面加载问题,首先应该考虑是否是由于代理冲突引起的。通过设置 multi_proxy=True 参数可以解决这个问题。此外,建议使用 pytest-xdist 进行多线程测试,这是 SeleniumBase 官方支持的方式,可以确保线程安全和资源管理。如果必须在不使用 pytest-xdist 的情况下进行多线程处理,需要格外小心,并确保正确地管理线程锁和资源。