news 2026/7/2 22:26:55

告别Selenium!用DrissionPage+ChromiumPage实现高效Web自动化登录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
告别Selenium!用DrissionPage+ChromiumPage实现高效Web自动化登录

1. 项目概述:为什么是时候告别Selenium了?

如果你和我一样,在过去几年里深度依赖Selenium进行Web自动化测试或数据抓取,那你一定对下面这些场景感同身受:为了一个简单的登录操作,不得不写几十行代码来等待元素加载、处理弹窗、应对动态内容;浏览器驱动版本不匹配导致脚本突然崩溃;网站稍微更新一下前端框架,原本稳定的定位器就集体失效,维护成本高得吓人。更头疼的是,随着反爬技术的升级,Selenium驱动的浏览器特征越来越容易被网站识别,轻则返回验证码,重则直接封禁IP。这些痛点,几乎成了每个自动化工程师的“日常”。

最近,一个名为DrissionPage的Python库,搭配其内置的ChromiumPage模式,正在悄然改变这个局面。它并非要完全颠覆Selenium,而是提供了一种更现代、更“丝滑”的替代方案。简单来说,DrissionPage将浏览器自动化(如Selenium)和网络请求(如Requests)的能力融合在了一起。你可以把它理解为一个“双模式”工具:在“ChromiumPage”模式下,它直接通过CDP(Chrome DevTools Protocol)协议与无头或有头Chrome/Edge浏览器通信,绕过了传统的WebDriver;在“SessionPage”模式下,它又能像Requests一样直接发送HTTP请求,高效获取静态内容。

这种设计带来的直接好处就是效率与稳定性的双重提升。对于登录这种典型场景,我们不再需要笨重地等待整个页面加载完毕,可以直接拦截网络请求、修改请求参数,或者混合使用浏览器渲染和直接请求,用最合适的方式完成认证。脚本的运行速度更快,浏览器的资源占用更低,并且由于减少了特征暴露,被反爬机制识别的风险也显著降低。

这篇文章,我将以一个完整的Web自动化登录项目为例,手把手带你从零开始,用DrissionPage+ChromiumPage实现一套更优雅、更健壮的解决方案。无论你是想自动化登录某个管理后台进行日常操作,还是需要稳定地抓取登录后才能访问的数据,这套方法都能让你事半功倍。我们会涵盖环境搭建、核心概念、登录策略选择、完整代码实现以及大量我踩过坑才总结出的实战技巧。

2. 核心工具解析:DrissionPage与ChromiumPage的独特优势

在深入代码之前,我们必须先理解手中的“利器”。很多人第一次接触DrissionPage会感到困惑:它和Selenium、Playwright、Puppeteer有什么区别?为什么说它更适合处理现代Web应用的登录?

2.1 DrissionPage的“双模式”架构

DrissionPage的核心思想是“混合动力”。它不像Selenium那样只能通过WebDriver驱动浏览器,也不像Requests那样只能处理简单的HTTP请求。它提供了两种主要的页面对象:

  1. SessionPage: 基于requestslxml构建。它模拟浏览器发送HTTP请求,并解析返回的HTML文档。它的优势是极快,因为不需要启动和渲染浏览器,适合获取静态页面或API数据。你可以用它来获取登录页面的表单结构、提交登录请求(如果登录是简单的POST请求的话)。

  2. ChromiumPage (或WebPage): 这是本文的重点。它通过CDP协议直接与Chromium内核的浏览器(如Chrome, Edge, Opera)通信。这与Playwright和Puppeteer的通信方式类似,但比Selenium的WebDriver协议更底层、更高效。它能够执行所有浏览器操作:点击、输入、执行JavaScript、监听网络请求等。

最关键的是,这两种模式可以在同一个脚本中无缝切换。例如,你可以用SessionPage快速获取到登录所需的csrf_token,然后用ChromiumPage打开浏览器,填充表单并提交。这种灵活性是单一工具难以比拟的。

2.2 为何ChromiumPage模式比传统Selenium更“丝滑”?

这里说的“丝滑”,主要体现在以下几个方面:

  • 启动与通信速度: Selenium需要通过WebDriver作为中间代理,而ChromiumPage直接通过CDP与浏览器对话,减少了中间环节,启动和指令响应的延迟更低。
  • 更强大的浏览器控制: CDP协议提供了比WebDriver更丰富的功能,例如精确的网络请求拦截与修改、详细的性能分析、对Service Worker的控制等。这对于处理复杂的登录流程(如OAuth 2.0跳转、单点登录SSO)至关重要。
  • 更低的特征指纹: 虽然无法做到完全隐身,但通过CDP直接控制,可以更容易地调整浏览器环境参数,隐藏一些自动化特征。DrissionPage也内置了一些优化选项。
  • 更简洁的API: DrissionPage的API设计非常Pythonic,链式调用和智能等待让代码更简洁。例如,page.ele(‘#username’).input(‘your_name’)一行代码就完成了查找元素和输入操作,并且内部包含了智能等待,避免了你手动写WebDriverWait

2.3 环境准备与安装

理论说再多不如动手一试。首先,我们准备好环境。我强烈建议使用Python 3.8及以上版本,并使用虚拟环境来管理依赖。

# 1. 创建并进入虚拟环境 (可选但推荐) python -m venv dp_env source dp_env/bin/activate # Linux/macOS # dp_env\Scripts\activate # Windows # 2. 安装DrissionPage pip install drissionpage # 3. 确保你有可用的Chromium内核浏览器 # DrissionPage会尝试自动查找系统中的Chrome或Edge。 # 如果你需要指定浏览器路径,可以在代码中配置。

安装完成后,你可以通过一个简单的命令来测试浏览器是否可用,但这通常不是必须的,因为DrissionPage会在首次运行时自动处理。

注意: 和Selenium需要下载对应版本的WebDriver不同,DrissionPage的ChromiumPage模式依赖于浏览器自带的CDP接口。只要你的Chrome/Edge版本不是过于古老(通常近两年的稳定版均可),它就能工作。这省去了管理驱动版本的麻烦。

3. 登录策略深度剖析:针对不同场景的四种武器

面对一个登录页面,盲目地开始写点击和输入代码是低效的。我们需要先分析登录的类型,然后选择最合适的策略。根据我的经验,Web登录大致可以分为以下几类,而DrissionPage为每一类都提供了相应的“武器”。

3.1 策略一:经典表单提交(SessionPage直接请求)

这是最简单、最快速的登录方式。适用于登录表单是简单的HTML表单,提交后是一个标准的POST请求,且不涉及复杂的JavaScript验证或动态令牌。

如何识别: 打开浏览器开发者工具(F12),切换到“网络(Network)”选项卡,勾选“保留日志(Preserve log)”。在登录页面输入账号密码点击登录,观察网络请求。如果看到一个POST请求,其Form DataPayload中清晰包含了你的用户名、密码和其他可能固定的字段(如一个csrf_token),那么很可能适用此策略。

DrissionPage实现思路

  1. SessionPage访问登录页面,解析HTML,获取表单中隐藏的字段(如csrf_token,authenticity_token)。
  2. 构造一个字典,包含所有必需的参数:账号、密码、以及获取到的令牌。
  3. 使用SessionPagepost方法,直接向登录接口发送请求。
  4. 检查返回的响应,如状态码、跳转或Cookies,来判断是否登录成功。

优势: 速度极快,无需启动浏览器,资源消耗极小。劣势: 无法处理需要JavaScript渲染才能生成的令牌,或登录后依赖浏览器环境的重定向。

3.2 策略二:模拟用户交互(ChromiumPage核心方法)

这是最通用、最能模拟真人操作的方法。适用于绝大多数现代网站,特别是那些登录按钮绑定了复杂JS事件、使用了图片验证码、或登录流程包含多步跳转的网站。

如何识别: 几乎任何有可视化登录页面的网站都适用。尤其是当你发现直接发送POST请求无效,或者登录参数无法从静态HTML中简单获取时。

DrissionPage实现思路

  1. 创建ChromiumPage对象,打开登录页面。
  2. 使用ele()方法定位用户名、密码输入框和登录按钮。DrissionPage的定位语法非常灵活,支持CSS选择器、XPath、文本内容等。
  3. 使用input()方法输入文本,click()方法点击按钮。
  4. 利用wait方法等待登录成功后的页面元素出现(如用户头像、退出按钮)。

优势: 通用性强,能应对复杂的交互逻辑和前端框架。劣势: 速度相对较慢,需要启动浏览器。

3.3 策略三:混合模式攻坚(SessionPage + ChromiumPage)

这是DrissionPage的杀手锏,用于处理那些“硬骨头”。例如,登录页面的csrf_token是通过JavaScript动态生成的,但提交登录后的会话管理又依赖于浏览器环境。

实战场景: 网站A的登录页面有一个由前端JS计算生成的动态令牌。你无法直接从HTML源码中获取它。但登录后的跳转和Cookie设置,又需要在一个真实的浏览器会话中完成。

DrissionPage实现思路

  1. ChromiumPage打开登录页面,让页面完整执行JS,生成所有必要的元素和令牌。
  2. ChromiumPage对象中提取当前页面的HTML源码(此时源码已是JS执行后的状态)。
  3. 将这个HTML源码交给一个SessionPage对象去解析,提取出动态生成的令牌。
  4. 再用SessionPage构造并发送POST请求。或者,你也可以选择继续用ChromiumPage来填充和提交表单,但此时你已经拿到了关键的动态参数。

这种方法结合了两种模式的优点,既处理了动态内容,又在某些环节保持了高效。

3.4 策略四:网络请求拦截与修改

这是应对高级反爬和复杂认证流程的“手术刀”。你可以监听浏览器发出的所有网络请求,在关键时刻(比如登录请求发出前)修改其请求头、参数或载荷。

实战场景: 网站B的登录请求中,除了常规参数,还包含一个由浏览器指纹生成的、每次都不一样的签名(sign)。单纯模拟点击无法绕过。

DrissionPage实现思路

  1. 在启动ChromiumPage时,设置网络监听。
  2. 在跳转到登录页和点击登录按钮之间,编写逻辑来等待特定的登录请求URL出现。
  3. 当监听到这个请求时,回调函数会被触发,你可以在这个函数里修改请求的Form Data,添加上你计算好的签名。
  4. 放行修改后的请求,完成登录。
from DrissionPage import ChromiumPage def on_request(request): if ‘login.api’ in request.url: # 修改请求的post data new_data = request.post_data new_data[‘signature’] = calculate_signature(new_data) request.post_data = new_data page = ChromiumPage() page.listen.start(‘login.api’) # 开始监听包含该字符串的请求 page.listen.add(on_request) page.get(‘https://example.com/login‘) # ... 定位并点击登录按钮 # 监听器会自动工作,修改请求

优势: 能力强大,可以精准控制请求,用于破解一些加密参数。劣势: 实现较为复杂,需要深入分析网络请求。

4. 完整代码实战:以模拟交互方式实现GitHub登录

我们选择一个经典的、有一定复杂度的场景——GitHub登录,来演示策略二(模拟用户交互)的完整实现。GitHub登录页面有JavaScript增强,并且成功后会有一个跳转,非常适合用ChromiumPage来操作。

4.1 项目结构与基础配置

首先,我们规划一下代码结构。一个好的结构能让脚本更易维护。

github_auto_login/ ├── config.py # 配置文件,存放账号、密码、URL等敏感信息 ├── login_core.py # 核心登录逻辑类 ├── main.py # 主程序入口 └── requirements.txt # 依赖列表

config.py: 我们将敏感信息放在这里,不要硬编码在脚本中。

# config.py GITHUB_LOGIN_URL = ‘https://github.com/login‘ GITHUB_USERNAME = ‘your_username‘ # 替换为你的用户名 GITHUB_PASSWORD = ‘your_password‘ # 替换为你的密码,切勿提交到版本库! # 成功登录后的标识元素,用于验证 LOGIN_SUCCESS_SIGNAL = ‘[data-test-selector=“user-nav”]‘ # GitHub右上角用户导航栏

4.2 核心登录类实现 (login_core.py)

这是重头戏。我们将创建一个GitHubLogin类,封装所有登录细节。

# login_core.py from DrissionPage import ChromiumPage from config import GITHUB_LOGIN_URL, GITHUB_USERNAME, GITHUB_PASSWORD, LOGIN_SUCCESS_SIGNAL import time from typing import Optional, Tuple class GitHubLogin: “”“GitHub自动化登录类”“” def __init__(self, headless: bool = False, timeout: float = 10): “”“ 初始化登录器 :param headless: 是否使用无头模式(不显示浏览器界面) :param timeout: 默认超时时间(秒) “”“ # 初始化ChromiumPage,可以传递配置字典 self.page = ChromiumPage(addr_driver_opts=None) # addr_driver_opts=None 让库自动管理 self.page.set.timeout(timeout) # 设置全局查找元素超时 self.headless = headless if headless: self.page.set.headless(True) # 启动后设置为无头模式 def _locate_login_elements(self) -> Tuple[Optional[object], Optional[object], Optional[object]]: “”“定位登录页面上的关键元素:用户名框、密码框、登录按钮”“” try: # 使用CSS选择器定位。GitHub登录页面的输入框有明确的id。 username_input = self.page.ele(‘#login_field‘) password_input = self.page.ele(‘#password‘) # 登录按钮可以用属性选择器 submit_button = self.page.ele(‘input[type=“submit”]‘) return username_input, password_input, submit_button except Exception as e: print(f“定位登录元素失败: {e}“) # 可以尝试截图,方便调试 self.page.get_screenshot(‘debug_locate_failed.png‘, full_page=True) return None, None, None def login(self) -> bool: “”“执行登录流程,返回是否成功”“” print(“正在打开GitHub登录页面...“) self.page.get(GITHUB_LOGIN_URL) # 等待页面主要内容加载 self.page.wait.load_start() print(“正在定位登录表单...“) username_ele, password_ele, submit_ele = self._locate_login_elements() if not all([username_ele, password_ele, submit_ele]): print(“错误:未能找到所有必需的登录元素。“) return False print(“正在输入用户名和密码...“) # 清空可能存在的默认值,然后输入 username_ele.input(‘‘) # 先清空 username_ele.input(GITHUB_USERNAME) time.sleep(0.5) # 小延迟,模拟真人输入节奏 password_ele.input(‘‘) password_ele.input(GITHUB_PASSWORD) time.sleep(0.5) print(“正在提交登录...“) submit_ele.click() # 等待页面跳转或加载完成。登录成功后,GitHub通常会重定向到首页或用户页。 # 我们等待一个登录成功后才会出现的元素作为标志。 try: # 等待最多15秒,直到成功信号元素出现 success_ele = self.page.wait.ele_loaded(LOGIN_SUCCESS_SIGNAL, timeout=15) if success_ele: print(“✅ 登录成功!当前页面标题:”, self.page.title) # 可以进一步获取登录后的Cookies,用于后续SessionPage请求 # cookies = self.page.cookies() # print(“获取到的Cookies:”, cookies) return True else: print(“❌ 登录失败:未检测到成功登录的标识。“) return False except Exception as e: print(f“❌ 登录过程中出现异常或超时: {e}“) # 再次截图,有助于分析失败原因(如验证码、错误提示) self.page.get_screenshot(‘login_failed.png‘, full_page=True) return False def close(self): “”“关闭浏览器”“” if self.page: self.page.quit() print(“浏览器已关闭。“) def __enter__(self): “”“支持with语句上下文管理”“” return self def __exit__(self, exc_type, exc_val, exc_tb): “”“退出上下文时自动关闭浏览器”“” self.close()

4.3 主程序与执行 (main.py)

主程序负责协调和运行。

# main.py from login_core import GitHubLogin import sys def main(): “”“主函数”“” # 使用上下文管理器,确保即使出错浏览器也会被关闭 with GitHubLogin(headless=False, timeout=15) as login_tool: # 调试时设为False看界面 success = login_tool.login() if success: print(“\n登录成功,可以在此处继续后续自动化操作...“) # 示例:跳转到个人仓库页面 # login_tool.page.get(‘https://github.com/your_username?tab=repositories‘) # ... 其他操作 input(“按回车键退出并关闭浏览器...“) # 暂停,方便观察 else: print(“\n登录失败,程序退出。“) sys.exit(1) if __name__ == ‘__main__‘: main()

4.4 代码逐行解析与关键技巧

  1. 初始化 (__init__):

    • ChromiumPage(addr_driver_opts=None): 这是最简单的初始化方式。库会自动寻找系统中的浏览器,并启动一个可用的CDP连接端口。你也可以指定浏览器路径和端口,实现更精细的控制。
    • page.set.timeout(): 设置全局的等待超时。这是非常重要的一步,它决定了ele()等方法在查找元素时会等待多久。默认值可能不够,对于较慢的页面建议设置为10-15秒。
  2. 元素定位 (_locate_login_elements):

    • page.ele(‘#login_field‘)ele()方法是核心,它接受CSS选择器、XPath或文本内容。这里使用ID选择器,因为GitHub的输入框ID是固定的,这是最稳定可靠的定位方式。
    • 定位器优先级建议ID>Name>CSS Selector>XPath。尽量避免使用依赖于页面结构且容易变化的XPath。
    • 定位失败时,我们返回None并截图。这个截图功能是调试神器,能让你直观地看到脚本运行到哪一步时页面状态不对。
  3. 输入与点击 (login方法):

    • input(‘‘): 在输入前先清空,这是一个好习惯。有些输入框可能有占位符或缓存值。
    • time.sleep(0.5): 这里我故意加了一个小延迟。虽然DrissionPage的inputclick本身很稳定,但在关键操作间加入短暂延迟,可以更好地模拟人类操作节奏,有时能避免一些前端框架的检测。这是对抗反爬的一个小技巧
    • submit_ele.click(): 点击登录按钮。
  4. 等待与验证:

    • page.wait.ele_loaded(LOGIN_SUCCESS_SIGNAL, timeout=15): 这是最关键的一行代码之一wait.ele_loaded会等待指定的元素出现在DOM中。我们使用登录成功后页面独有的元素(如用户导航栏)作为成功标志。这比等待页面标题变化或URL跳转更可靠。
    • 如果等待超时,则判定为登录失败。失败时再次截图,有助于分析是密码错误、出现了验证码,还是页面结构变了。
  5. Cookies获取:

    • 代码注释中展示了page.cookies()。一旦登录成功,你可以获取到当前会话的所有Cookies。这些Cookies可以保存下来(如用json模块写入文件),后续在SessionPage中直接加载使用,就能以已登录状态访问其他需要认证的页面,无需再次启动浏览器。这是实现“一次登录,多次使用”的高效方法。

5. 进阶实战与避坑指南

掌握了基础登录后,我们来看看在实际项目中更可能遇到的复杂情况以及如何应对。

5.1 处理验证码(图片、滑块、点选)

验证码是自动化登录最大的拦路虎。DrissionPage本身不提供识别验证码的功能,但它为我们集成第三方服务或本地模型提供了完美的操作界面。

思路: “识别”和“操作”分离。

  1. 触发验证码: 用ChromiumPage正常操作,直到验证码出现。
  2. 获取验证码图片
    • 找到验证码图片的<img>元素。
    • 获取其src属性(可能是Base64数据或一个URL)。
    • 如果是URL,可以用SessionPage下载图片;如果是Base64,直接解码保存。
    img_ele = page.ele(‘#captcha-img‘) src = img_ele.attr(‘src‘) # 处理src,保存为本地文件 captcha.png
  3. 调用识别服务
    • 商业API: 如联众、打码兔等,调用其SDK或HTTP API。
    • 本地OCR: 使用pytesseract(Tesseract)或ddddocr(针对滑块)等库。
    # 示例:使用打码兔API (伪代码) import requests def recognize_captcha(image_path): with open(image_path, ‘rb‘) as f: img_data = f.read() resp = requests.post(‘https://api.damatu.com/...‘, data={‘image‘: img_data}) return resp.json()[‘result‘] # 返回识别结果
  4. 输入结果并提交: 将识别结果填入对应输入框,然后继续流程。
    code = recognize_captcha(‘captcha.png‘) input_ele = page.ele(‘#captcha-input‘) input_ele.input(code) submit_ele.click()

重要心得: 对于复杂验证码(如滑块),纯自动化破解的难度和成本很高。在商业项目中,评估是否值得投入。有时,更好的策略是设计流程让验证码出现时通知人工处理,或者寻找没有验证码的备用登录接口(如移动端API)。

5.2 处理动态加载与前端框架(React/Vue)

现代单页应用(SPA)大量使用动态加载,元素可能不会一次性全部出现。

DrissionPage的应对

  • 智能等待是核心: 充分利用wait方法族。除了wait.ele_loaded,还有wait.ele_displayed(等待元素显示)、wait.doc_loaded(等待文档加载完成)等。
  • 不要滥用time.sleep: 固定休眠是糟糕的做法。应该基于事件或元素状态来等待。
  • 示例:等待一个由Vue渲染的按钮
    # 错误做法:time.sleep(5) # 正确做法: submit_btn = page.wait.ele_displayed(‘button:has-text(“登录”)‘, timeout=10) # `:has-text()`是DrissionPage支持的伪类,非常实用 submit_btn.click()

5.3 登录状态维持与Cookies管理

登录成功后,如何保持会话并用于后续操作?

  1. 保存Cookies

    if login_success: cookies = page.cookies() # 获取cookies列表 import json with open(‘github_cookies.json‘, ‘w‘) as f: json.dump(cookies, f) print(“Cookies已保存。“)
  2. 加载Cookies到SessionPage

    from DrissionPage import SessionPage import json s_page = SessionPage() with open(‘github_cookies.json‘, ‘r‘) as f: cookies = json.load(f) s_page.cookies.set(cookies) # 为SessionPage设置cookies # 现在访问需要登录的页面 s_page.get(‘https://github.com/notifications‘) # 检查页面内容,确认已登录 if ‘Inbox‘ in s_page.html: print(“使用Cookies登录成功!“)

    这种方式效率极高,适合后续大量的数据抓取任务。

5.4 常见失败原因排查清单

当你运行脚本失败时,可以按照这个清单逐一排查:

问题现象可能原因排查步骤与解决方案
启动浏览器失败/连接超时1. 系统中未安装Chrome/Edge。
2. 浏览器版本太旧。
3. 端口被占用。
1. 安装或更新Chrome/Edge到最新稳定版。
2. 在代码中指定浏览器路径:ChromiumPage(browser_path=‘/path/to/chrome‘)
3. 检查是否有其他自动化程序在运行。
找不到元素 (ele()返回None)1. 定位器写错了。
2. 页面尚未加载完成。
3. 元素在iframe内。
4. 页面结构已更新。
1. 使用浏览器开发者工具(F12)的“检查”功能,确认元素的选择器。
2. 在page.get()后添加page.wait.load_start()或等待特定元素。
3. 使用page.get_frame(‘iframe_id‘)切换到iframe内再查找。
4. 更新你的定位器。务必使用相对稳定、有语义的ID或Class
输入或点击无效1. 元素被遮挡。
2. 元素是<div>模拟的,非标准表单控件。
3. 有前置的JS验证。
1. 截图查看页面状态。尝试page.scroll.to_see(ele)滚动到元素可见。
2. 尝试使用ele.run_js(‘arguments[0].click();‘, ele)执行原生JS点击。
3. 尝试先触发focus事件:ele.run_js(‘arguments[0].focus();‘, ele),再输入。
登录后检测不到成功标志1. 登录失败(账号密码错误、验证码)。
2. 成功标志元素定位器失效。
3. 登录后跳转的页面不同。
1.首先截图!查看失败瞬间的页面,是否有错误提示。
2. 检查成功标志是否仍然有效。可以尝试用更通用的选择器,如a[href*=“logout”](包含logout的链接)。
3. 登录后等待URL变化:page.wait.url_change(‘https://github.com/‘)
脚本被网站识别浏览器自动化特征暴露。1. 尝试启用page.set.user_agent()更换UA。
2. 尝试page.set.no_imgs(True)禁止加载图片加速。
3.最有效:在关键操作间增加随机延迟,并模拟鼠标移动轨迹(DrissionPage未来版本可能支持)。
4. 考虑降级使用SessionPage直接请求,如果接口允许的话。

6. 性能优化与最佳实践

要让你的自动化脚本不仅能用,而且高效、稳定、易于维护,下面这些经验值得你参考。

6.1 配置优化:让浏览器更快更轻

创建ChromiumPage时,可以通过ChromiumOptions对象传递大量启动参数,这和Selenium的Options类似。

from DrissionPage import ChromiumOptions # 创建配置对象 co = ChromiumOptions() co.no_imgs(True) # 禁止加载图片,大幅提升速度 co.headless(True) # 无头模式 co.set_argument(‘--disable-blink-features=AutomationControlled‘) # 尝试隐藏自动化特征 co.set_argument(‘--window-size=1920,1080‘) # 设置窗口大小 # 可以禁用GPU、沙箱等,根据环境调整 # co.set_argument(‘--disable-gpu‘) # co.set_argument(‘--no-sandbox‘) # 将配置传递给ChromiumPage page = ChromiumPage(addr_driver_opts=co)

关键参数建议

  • --disable-blink-features=AutomationControlled: 有助于隐藏一些自动化特征,但非绝对。
  • --no-sandbox: 在Linux服务器或无GUI环境下运行时,如果遇到启动问题,可以尝试加上此参数。
  • --disable-dev-shm-usage: 在Docker容器中运行时,如果内存不足,可以加上此参数。

6.2 封装与复用:构建你自己的自动化工具库

不要每次都从头写登录脚本。将通用功能封装成函数或类。

  • Cookie管理器: 一个负责保存、加载、更新Cookies的类。
  • 验证码处理器: 一个抽象类,定义get_captcha_imagesubmit_captcha_code接口,然后为不同的验证码服务(如云打码、本地OCR)实现具体子类。
  • 页面对象模型 (Page Object Model, POM): 对于大型项目,为每个重要页面(如LoginPage, DashboardPage)创建一个类,将页面元素定位和操作封装在里面。主脚本只调用这些类的方法,使得代码清晰,易于维护。

6.3 异常处理与日志记录

健壮的脚本必须能妥善处理异常,并留下清晰的日志供排查。

import logging from DrissionPage.errors import ElementNotFoundError logging.basicConfig(level=logging.INFO, format=‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘, handlers=[logging.FileHandler(‘auto_login.log‘), logging.StreamHandler()]) logger = logging.getLogger(__name__) class RobustGitHubLogin(GitHubLogin): def login(self): try: self.page.get(GITHUB_LOGIN_URL) self.page.wait.load_start() # ... 登录操作 success_ele = self.page.wait.ele_loaded(LOGIN_SUCCESS_SIGNAL, timeout=20) if success_ele: logger.info(“GitHub登录成功。”) return True else: logger.warning(“登录成功标识未找到,可能登录失败。”) return False except ElementNotFoundError as e: logger.error(f“在等待或查找元素时出错: {e}“) self.page.get_screenshot(‘error_element_not_found.png‘) return False except Exception as e: logger.exception(f“登录过程中发生未预期异常: {e}“) # 会记录完整的堆栈跟踪 return False

6.4 何时选择DrissionPage,何时选择Selenium/Playwright?

这是一个很实际的问题。没有银弹,只有最适合的工具。

  • 选择 DrissionPage + ChromiumPage 当

    • 你需要混合使用浏览器渲染和直接HTTP请求(这是它的最大优势)。
    • 你希望有比Selenium更简洁的API和更快的执行速度。
    • 你的项目主要是Python技术栈,且希望依赖更轻量(相比Playwright需要安装浏览器二进制文件)。
    • 你需要精细的网络请求拦截与修改能力。
  • 坚持使用 Selenium 当

    • 你的团队或现有项目对Selenium有深厚的积累和封装。
    • 你需要支持多种非Chromium内核浏览器(如Firefox, Safari)。虽然DrissionPage的WebPage模式理论上支持,但成熟度可能不如Selenium。
    • 你需要与Grid或SaaS服务(如BrowserStack, Sauce Labs)进行深度集成。
  • 考虑 Playwright 当

    • 你需要跨浏览器(Chromium, Firefox, WebKit)的高度一致性测试。
    • 你非常看重自动等待、强大的录制工具和微软官方的支持维护。
    • 你的项目可以使用Node.js/Python/C#/Java多种语言。

我个人的体会是:对于以Python为主、且需要应对复杂Web交互和网络请求的自动化任务(非纯测试),DrissionPage提供了一个极具吸引力的选择。它降低了在Requests和Selenium之间切换的心智负担,用一套统一的API解决了两类问题。而在纯粹的Web自动化测试领域,Playwright目前展现出的生态和工具链优势可能更大。至于Selenium,它依然是行业的基石,拥有最广泛的社区和生态,但在面对现代Web应用的复杂性和对执行效率有更高要求的场景下,后起之秀们确实带来了更“丝滑”的体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 22:25:47

2024年iOS自动化测试指南:告别Facebook版WDA,拥抱Appium官方驱动

1. 项目概述&#xff1a;为什么2024年要告别Facebook版WDA&#xff1f; 如果你是一名iOS自动化测试工程师&#xff0c;或者正在尝试将Appium引入你的移动端测试流程&#xff0c;那么“Facebook版WebDriverAgent”这个名字你一定不陌生&#xff0c;甚至可能因为它而头疼过。在过…

作者头像 李华
网站建设 2026/7/2 22:23:50

AI在自动化测试中的角色定位:从智能助手到自主测试的实践与思考

1. 项目概述&#xff1a;AI在测试领域的角色之争 最近和几个测试团队的朋友聊天&#xff0c;发现一个挺有意思的现象&#xff1a;大家一提到“AI自动化测试”&#xff0c;态度就两极分化。一部分人觉得AI就是个高级点的脚本生成器&#xff0c;顶多算个“助手”&#xff0c;核心…

作者头像 李华
网站建设 2026/7/2 22:21:54

Appium Android自动化测试入门:从环境搭建到实战脚本编写

1. 项目概述&#xff1a;为什么我们需要Appium自动化如果你是一名Android开发者或者测试工程师&#xff0c;每天重复着在手机上点点点、输入输入再输入的操作&#xff0c;是不是偶尔会感到一丝枯燥和低效&#xff1f;尤其是在回归测试阶段&#xff0c;一个功能改动可能需要你把…

作者头像 李华
网站建设 2026/7/2 22:20:29

iOS自动化测试:MAC通过Xcode连接真机与WDA环境搭建指南

1. 项目概述&#xff1a;为什么要在MAC上用Xcode连接真机做自动化测试&#xff1f; 作为一名在iOS开发和测试领域摸爬滚打了多年的老手&#xff0c;我见过太多团队在自动化测试的起步阶段就栽了跟头。最常见的误区就是&#xff1a;只在模拟器上跑自动化脚本&#xff0c;觉得又…

作者头像 李华