Featured image of post DrissionPage 完全指南:比 Selenium 更好用的 Python 网页自动化工具
Python

DrissionPage 完全指南:比 Selenium 更好用的 Python 网页自动化工具

DrissionPage 完全指南:比 Selenium 更好用的 Python 网页自动化工具

前言

DrissionPage 是一个基于 Python 的网页自动化工具,由 g1879 开发。名称含义:Drission = Driver + Session,将浏览器控制和 HTTP 数据包收发合二为一。相比 Selenium,它无需下载驱动、速度更快、语法更简洁,是 Python 网页自动化的利器。

1. 核心特性

特性说明
自研内核不基于 webdriver,无需为不同浏览器下载驱动
双模式合一浏览器模式(d)+ 数据包模式(s),可随时切换
极简定位语法#id.classtext 比 Selenium 简洁得多
跨 iframe直接查找元素,无需 switch_to
多标签页同时操作多个标签页,无需切换焦点
内置等待重试无需 sleep,自动等待元素加载
整页截图包括视口外的部分
配置持久化ini 文件保存配置,自动调用

2. 安装

pip install DrissionPage

# 升级
pip install DrissionPage --upgrade

# 使用国内镜像
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple DrissionPage

环境要求

  • Python 3.6+
  • Chromium 内核浏览器(Chrome、Edge)

3. 核心概念

3.1 两种模式

模式说明优点缺点
d 模式(Driver)控制浏览器可点击、填写、执行 JS占内存,速度慢
s 模式(Session)收发数据包速度快几个数量级不能操作页面

3.2 主要对象

# 浏览器控制
from DrissionPage import Chromium

# 数据包模式
from DrissionPage import SessionPage

# 配置类
from DrissionPage import ChromiumOptions

4. ChromiumPage — 浏览器自动化

4.1 基本使用

from DrissionPage import Chromium

# 创建浏览器对象
browser = Chromium()

# 获取标签页
tab = browser.latest_tab

# 访问网页
tab.get('https://www.baidu.com')

# 获取元素并交互
ele = tab.ele('#kw')          # 获取搜索框
ele.input('DrissionPage')     # 输入文本
tab('#su').click()            # 点击搜索按钮

# 获取结果
links = tab.eles('tag:h3')
for link in links:
    print(link.text)

4.2 连接已打开的浏览器

from DrissionPage import Chromium, ChromiumOptions

co = ChromiumOptions()
co.set_address('127.0.0.1:9222')
browser = Chromium(addr_or_opts=co)
tab = browser.latest_tab

4.3 浏览器配置

from DrissionPage import Chromium, ChromiumOptions

co = ChromiumOptions()

# 常用配置(支持链式调用)
co.headless()                          # 无头模式
co.no_imgs(True)                       # 不加载图片
co.mute(True)                          # 静音
co.incognito()                         # 匿名模式
co.set_argument('--no-sandbox')        # 无沙盒(Linux 常用)
co.set_argument('--window-size', '1920,1080')  # 窗口大小
co.set_browser_path('/usr/bin/google-chrome')  # 浏览器路径
co.auto_port(True)                     # 自动分配端口

# 添加插件
co.add_extension('/path/to/extension')

# 保存配置到 ini 文件
co.save('/path/to/config.ini')

# 加载配置
co = ChromiumOptions(ini_path='/path/to/config.ini')

# 启动浏览器
browser = Chromium(addr_or_opts=co)

5. SessionPage — HTTP 请求

5.1 GET 请求

from DrissionPage import SessionPage

page = SessionPage()

# 普通请求
page.get('https://example.com')

# 带参数
page.get('https://example.com', params={'page': 1})

# 带 headers 和 cookies
page.get('https://example.com',
         headers={'Referer': 'https://google.com'},
         cookies={'token': 'abc123'})

# 带代理
page.get('https://example.com',
         proxies={'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'})

# 读取本地文件
page.get('/path/to/file.html')

# 查找元素(语法与浏览器模式一致!)
items = page.eles('tag:h3')
for item in items:
    print(item.text, item.link)

5.2 POST 请求

from DrissionPage import SessionPage

page = SessionPage()

# form 表单
page.post('https://example.com/login', data={'user': 'admin', 'pass': '123'})

# JSON 数据
page.post('https://api.example.com', json={'name': '张三', 'age': 25})

5.3 SessionPage 配置

page = SessionPage()

# 重试设置
page.set.retry_times(5)           # 重试次数
page.set.retry_interval(3)        # 重试间隔
page.set.timeout(20)              # 超时时间

# Headers
page.set.headers({'User-Agent': 'Mozilla/5.0...'})
page.set.header('Referer', 'https://example.com')

# Cookies
page.set.cookies([{'name': 'a', 'value': '1'}])
page.set.cookies.clear()

# 代理
page.set.proxies(http='127.0.0.1:1080', https='127.0.0.1:1080')

# SSL 验证
page.set.verify(False)

6. 混合模式(d/s 切换)

这是 DrissionPage 最强大的特性——浏览器模式和数据包模式可以互相切换,自动同步 cookies。

from DrissionPage import Chromium

tab = Chromium().latest_tab

# 用浏览器处理登录(d 模式)
tab.get('https://example.com/login')
tab.ele('#username').input('admin')
tab.ele('#password').input('123456\n')
tab.wait.url_change('https://example.com/dashboard')

# 切换到 s 模式爬取数据(速度快)
tab.change_mode()
items = tab.eles('.data-item')
for item in items:
    print(item.text)

# 切换回 d 模式
tab.change_mode('d')

典型场景

  • 登录验证严格 → 浏览器登录 → 切 s 模式爬数据
  • 页面由 JS 渲染 → d 模式读取 → 转 s 模式分析

7. 元素定位语法(核心亮点)

DrissionPage 的定位语法比 Selenium 简洁得多:

7.1 基本定位

# ID 定位
tab.ele('#username')           # id 为 username
tab.ele('#:ser')               # id 包含 ser

# Class 定位
tab.ele('.login-btn')          # class 为 login-btn
tab.ele('.^login')             # class 以 login 开头

# 文本定位(默认模糊匹配)
tab.ele('登录')                 # 文本包含"登录"
tab.ele('text=登录')            # 精确匹配"登录"

# 标签定位
tab.ele('tag:div')             # 第一个 div
tab.ele('tag:input@class=form-control')  # 配合属性

# CSS 选择器
tab.ele('css:.form-group input')

# XPath
tab.ele('xpath://div[@class="content"]')

7.2 属性定位

# 单属性 @
tab.ele('@id=one')             # id 为 one
tab.ele('@name=email')         # name 为 email
tab.ele('@placeholder')        # 有 placeholder 属性

# 多属性与 @@
tab.ele('@@class=form@@type=text')  # class=form 且 type=text

# 多属性或 @|
tab.eles('@|id=btn1@|id=btn2')  # id 为 btn1 或 btn2

# 否定 @!
tab.ele('@!type=hidden')       # type 不是 hidden

7.3 匹配模式

符号含义示例
=精确匹配@id=row1
:包含@id:ow
^开头@id^row
$结尾@id$w1

7.4 Selenium 对比

# 查找文本包含 'abc' 的元素
# DrissionPage
ele = tab('abc')
# Selenium
ele = driver.find_element(By.XPATH, '//*[contains(text(), "abc")]')

# 获取兄弟元素
# DrissionPage
ele1 = ele.next()
ele2 = ele.prev(index=2)
# Selenium
ele1 = ele.find_element(By.XPATH, './/following-sibling::*')

8. 元素操作

8.1 点击

ele.click()                    # 左键点击
ele.click(by_js=True)          # JS 点击(无视遮挡)
ele.click(by_js=None)          # 智能模式
ele.click.right()              # 右键
ele.click.middle()             # 中键(返回新 Tab)
ele.click.multi(times=2)       # 双击
ele.click.at(50, -50)          # 带偏移点击
ele.click.for_new_tab()        # 点击并获取新标签页

8.2 输入

ele.input('Hello')             # 输入文本
ele.input('Hello\n')           # 输入并回车
ele.input('new', clear=True)   # 先清空再输入
ele.clear()                    # 清空

# 组合键
from DrissionPage.common import Keys
ele.input(Keys.CTRL_A)         # 全选
ele.input(Keys.CTRL_C)         # 复制
ele.input((Keys.CTRL, 'a', Keys.DEL))  # Ctrl+A+Del

8.3 其他操作

ele.hover()                    # 悬停
ele.drag(50, 50)               # 拖拽到相对位置
ele.drag_to(ele2)              # 拖拽到另一个元素

# 修改元素
ele.set.innerHTML('<p>new</p>')
ele.set.property('value', 'new value')
ele.set.style('color', 'red')
ele.set.attr('data-id', '123')

# 获取信息
ele.text                       # 文本
ele.inner_html                 # 内部 HTML
ele.link                       # href/src
ele.tag                        # 标签名
ele.attr('href')               # 属性
ele.css('color')               # 样式值

9. 等待与重试

DrissionPage 内置智能等待,无需 sleep()

# 等待元素加载
tab.wait.eles_loaded('#dynamic-div', timeout=10)

# 等待元素显示
tab.wait.ele_displayed('#modal')

# 等待元素隐藏
tab.wait.ele_hidden('#loading')

# 等待元素删除
tab.wait.ele_deleted('#temp')

# 等待 URL 变化
tab.wait.url_change('https://example.com/dashboard')

# 等待 title 变化
tab.wait.title_change('登录成功')

# 等待新标签页
browser.wait.new_tab()

# 等待下载开始
mission = tab('#download-btn').click()
mission = tab.wait.download_begin()

# 等待下载完成
browser.wait.downloads_done(timeout=60)

# ele() 自动重试(默认超时 10 秒)
ele = tab.ele('#dynamic-element', timeout=5)

10. 标签页管理

from DrissionPage import Chromium

browser = Chromium()

# 获取标签页
tab = browser.latest_tab            # 最后激活的
tab1 = browser.get_tab(1)           # 按序号
tab2 = browser.get_tab(url='example')  # 按 URL

# 新建标签页
browser.new_tab('https://example.com')

# 点击后获取新标签页
new_tab = link.click.for_new_tab()
new_tab.wait.load_start()
print(new_tab.title)
new_tab.close()

# 多标签页协同
links = tab.eles('tag:a')
for link in links:
    new_tab = link.click.for_new_tab()
    new_tab.wait.load_start()
    print(new_tab.title)
    new_tab.close()

11. 截图与录像

# 整页截图
tab.get_screenshot(path='screenshots', name='full.png', full_page=True)

# 截取指定区域
tab.get_screenshot(path='tmp', name='part.png',
                   left_top=(0, 0), right_bottom=(800, 600))

# 元素截图
header = tab.ele('tag:header')
header.get_screenshot()

# 返回字节/base64
img_bytes = tab.get_screenshot(as_bytes='png')
img_b64 = tab.get_screenshot(as_base64='png')

# 页面录像
tab.screencast.set_save_path('video')
tab.screencast.set_mode.video_mode()
tab.screencast.start()
# ... 操作 ...
path = tab.screencast.stop()

12. 实战示例

12.1 自动登录

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.get('https://gitee.com/login')

tab.ele('#user_login').input('your_account')
tab.ele('#user_password').input('your_password')
tab.ele('@value=登 录').click()

tab.wait.url_change('https://gitee.com/dashboard')
print('登录成功!')

12.2 数据采集(s 模式)

from DrissionPage import SessionPage

page = SessionPage()

for i in range(1, 4):
    page.get(f'https://example.com/list?page={i}')
    items = page.eles('.item-title')
    for item in items:
        print(item.text, item.link)

12.3 登录后切换模式爬取

from DrissionPage import Chromium

tab = Chromium().latest_tab

# 浏览器登录
tab.get('https://example.com/login')
tab.ele('#username').input('admin')
tab.ele('#password').input('123456\n')
tab.wait.url_change('https://example.com/home')

# 切换到 s 模式快速爬取
tab.change_mode()
data = tab.eles('.data-row')
for row in data:
    print(row.text)

12.4 表单填写与文件上传

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.get('https://example.com/form')

# 填写表单
tab.ele('#name').input('张三')
tab.ele('#email').input('test@example.com')

# 选择下拉框
tab.ele('#city').click()
tab.ele('text=北京').click()

# 上传文件
tab.ele('#file-input').click.to_upload('/path/to/file.pdf')

# 提交
tab.ele('@type=submit').click()

12.5 文件下载

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.get('https://example.com/download')

# 点击下载
mission = tab('#download-btn').click.to_download(save_path='downloads')

# 等待下载完成
tab.wait.downloads_done(timeout=120)

13. 与 Selenium/Playwright 对比

特性DrissionPageSeleniumPlaywright
驱动自研内核基于 webdriver自研协议
驱动安装❌ 不需要✅ 需要✅ 需要
速度⚡ 快🐌 较慢⚡ 快
跨 iframe✅ 直接查找❌ 需 switch_to✅ 支持
多标签页✅ 同时操作❌ 需 switch_to✅ 支持
数据包模式✅ 内置 requests❌ 不支持❌ 不支持
模式切换✅ d/s 互切❌ 不支持❌ 不支持
定位语法✅ 极简❌ 较繁琐⚡ 较简洁
自动等待✅ 内置❌ 需 WebDriverWait✅ 内置
整页截图✅ 支持❌ 只截视口✅ 支持
shadow-root✅ 支持❌ 部分支持✅ 支持
配置管理✅ ini 文件❌ 代码配置❌ 代码配置
浏览器复用✅ 支持⚡ 需特殊配置❌ 不支持
学习曲线⭐ 简单⭐⭐ 中等⭐⭐ 中等

14. 定位语法速查表

语法说明示例
#id匹配 idtab.ele('#one')
.class匹配 classtab.ele('.p_cls')
text模糊匹配文本tab.ele('登录')
text=xxx精确匹配文本tab.ele('text=登录')
tag:xxx匹配标签tab.ele('tag:div')
css:xxxCSS 选择器tab.ele('css:.cls')
xpath:xxxXPathtab.ele('xpath://div')
@attr=val单属性匹配tab.ele('@id=one')
@@a=1@@b=2多属性与tab.ele('@@class=c@@text()=x')
`@a=1@b=2`
@!attr=val否定匹配tab.ele('@!id=one')

总结

DrissionPage 核心优势:

  • 无需驱动 — 自研内核,不依赖 webdriver
  • 双模式合一 — 浏览器 + 数据包,一键切换
  • 极简语法#id.classtext 比 Selenium 简洁 10 倍
  • 内置等待 — 自动重试,无需 sleep
  • 跨 iframe — 直接查找,无需 switch_to
  • 配置持久化 — ini 文件保存,自动加载

如果你厌倦了 Selenium 的繁琐配置和慢速度,DrissionPage 是绝佳的替代方案。

验证来源:DrissionPage 官方文档 (https://www.drissionpage.cn)

使用 Hugo 构建
主题 StackJimmy 设计