ThankNeko's Blog ThankNeko's Blog
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)

Hoshinozora

尽人事,听天命。
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)
  • Python笔记

    • 基础知识

    • 并发编程

    • 爬虫笔记

      • 爬虫相关介绍
      • Requests模块
      • BeautifulSoup模块
      • Xpath模块
      • DrissionPage模块
        • 网页自动化
          • 介绍
          • 方式
        • DrissionPage介绍
          • 介绍
          • 主要对象
          • 安装与导入
          • 基本逻辑
        • 浏览器启动配置
        • 浏览器连接
        • 浏览器对象
          • 获取标签页
          • 操作标签页
          • 浏览器信息
          • 浏览器操作
        • 标签页对象
          • 标签页设置
          • 标签页模式
          • 标签页请求
          • 标签页信息
          • 标签页操作
          • 动作链
        • 查找元素
          • 定位符介绍
          • 函数方法
          • 匹配符号
          • 匹配模式
          • 使用方法
        • 元素对象
          • 元素相对定位
          • 元素交互
          • 元素信息
        • 使用例子
          • 自动注册某网站
          • 自动爬取京东商品信息
      • JS逆向基础
    • 模块笔记

    • 后端笔记

  • C笔记

  • C++笔记

  • Arduino笔记

  • Web笔记

  • Dev
  • Python笔记
  • 爬虫笔记
Hoshinozora
2025-11-06
目录

DrissionPage模块

# 网页自动化

# 介绍

网页自动化,即通过程序让浏览器自动实现平时需要我们手动才能完成的任务,模拟人工执行重复性任务。

# 方式

网页自动化的方式通常如下两种:

  1. 直接向服务器发送数据包,获取需要的数据。

例如Urllib、Requests等模块就用于实现该方式。

优点是轻量级、速度快、便于多线程、分布式部署。

缺点是当数据包构成复杂,或者碰到加密时,开发难度直线上升。

  1. 控制浏览器跟网页进行交互。

例如Selenium、Playwright等模块就是用于实现该方式。

# DrissionPage介绍

# 介绍

DrissionPage是一个基于Python的网页自动化模块,它将两种网页自动化方式进行了整合,既能控制浏览器,又能收发数据包。兼顾浏览器自动化的便利性和Requests的高效率性。

用于操作浏览器的对象叫Driver,用于管理连接会话的对象叫Session,因此二者合一的名称即是Drission,而Page表示以页面为单位使用。

支持Chromium内核浏览器(如Chrome和Edge)、electron应用。

文档地址:https://drissionpage.cn/browser_control/intro

# 主要对象

# 浏览器对象

Chromium:浏览器对象。

浏览器类用于连接浏览器、管理标签页及其它和浏览器总体有关的操作。

浏览器类相当于总管,它可以作为浏览器入口,使用它产生Tab对象去操控每个标签页。

# Page对象

ChromiumPage:能管理浏览器本身的页面对象。

ChromiumPage将浏览器对象和第一个标签页对象进行封装,用于控制浏览器。

ChromiumPage和Chromium的区别是它生成的Tab对象是ChromiumTab,不能切换模式。

WebPage:整合浏览器控制和收发数据包于一体的页面对象。

其自身及其产生的Tab对象可切换模式,既可控制浏览器,也可收发数据包。

SessionPage:用于收发数据包的页面对象。

SessionPage将requests和lxml进行封装,用于收发数据包。

它把网络连接和结果解析封装成页面。操作逻辑和其它页面一致。

# Tab对象

MixTab:浏览器标签页对象。

由Chromium对象产生,一个对象控制一个实际的标签页。

ChromiumTab:浏览器标签页对象。

由ChromiumPage对象产生,和MixTab对象的区别是不可切换收发数据包模式。

# Element对象

ChromiumElement:浏览器元素对象。

SessionElement:静态元素对象。

ChromiumFrame:<iframe>元素对象,兼有标签页对象和元素特性。

ShadowRoot:shadow-root元素对象。

# 安装与导入

# 安装
pip install DrissionPage

# 导入路径
# from DrissionPage import ****:浏览器类、配置类、页面类
# from DrissionPage.errors import ****:异常
# from DrissionPage.common import ****:辅助工具
# from DrissionPage.items import ****:衍生对象,用于类型判断
1
2
3
4
5
6
7
8

# 基本逻辑

操作浏览器的基本逻辑有以下步骤:

  1. 创建浏览器对象,启动或接管浏览器。
  2. 获取一个Tab对象。
  3. 使用Tab对象获取标签页内需要的元素对象。
  4. 使用元素对象进行交互。

# 浏览器启动配置

**ChromiumOptions**类用于管理浏览器的初始化配置,可以手动指定配置,或从配置文件中读取配置来进行初始化。

浏览器启动后,再修改该配置没有任何效果。接管已打开的浏览器时,启动配置也是无效的。

但是可以对标签页进行临时的配置修改。

设置优先级:Tab对象设置 > Chromium对象设置 > Settings设置。

# 创建配置

类的初始化参数

  • read_file:是否从ini文件中读取配置信息,默认为True,为False则用默认配置创建。

  • ini_path:指定ini文件路径,默认为None,表示则读取内置ini文件。

# 浏览器启动配置类
from DrissionPage import ChromiumOptions

# 创建浏览器配置对象
co = ChromiumOptions()
1
2
3
4
5

# 修改配置

# 配置对象支持链式操作,例如co.no_imgs(True).save()

# 设置浏览器可执行文件路径
co.set_browser_path("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")

# 设置下载文件保存路径
co.set_download_path("path")

# 保存配置项到一个ini文件,传入None则保存到当前读取的配置文件
co.save("path")

# 设置用户文件夹路径,用于存储浏览器的使用痕迹、设置选项等,一般不需要指定
co.set_user_data_path("path")

# 保存配置项到固定的默认ini文件
co.save_to_default()

# 设置是否禁止加载图片
co.no_imgs(True)

# 设置是否静音
co.mute(True)

# 设置是否禁用JavaScript
co.no_js(True)

# 设置是否使用无痕模式启动
co.incognito(True)

# 设置是否使用无界面模式(无头模式)启动
co.headless(True)

# 设置是否使用全新环境启动浏览器
co.new_env(True)

# 设置是否忽略证书错误
co.ignore_certificate_errors(True)

# 设置是否自动分配端口,可以指定端口号范围
# 每个端口对应一个浏览器,设置该参数后,在创建浏览器对象时只会启动新的浏览器
co.auto_port(True)

# 是否仅连接已有浏览器,如连接浏览器失败会抛出异常,不会启动新浏览器
co.existing_only(True)

# 设置默认超时时间/页面加载超时时间/JS运行超时时间,单位为秒
# co.set_timeouts(base, page_load, script)
co.set_timeouts(base=10)

# 设置页面连接超时时的重试次数和重试间隔(秒)
co.set_retry(3, 5)

# 设置浏览器地址,支持IP:PORT格式和WS连接格式。
co.set_address("127.0.0.1:9333")

# 设置浏览器代理,该设置在浏览器启动时一次性设置,设置后不能修改,set_proxy("协议://ip:port")
co.set_proxy("http://localhost:1080")

# 设置User-Agent
co.set_user_agent(user_agent='Mozilla/5.0 (Macintos.....')

# 设置网页加载策略,无论设置哪种策略,加载时间都不会超过页面加载超时时间
# 加载策略是指强制页面停止加载的时机,如加载完DOM即停止,则不会加载图片资源,以提高自动化效率
# normal:阻塞进程,等待所有资源下载完成(默认)
# eager:DOM就绪即停止加载
# none:网页连接成功即停止加载
co.set_load_mode("normal")

# 设置浏览器内核启动参数,控制浏览器行为和初始状态co.set_argument("arg", "value")
# 带值的参数传入属性值,没有值的参数传入None,如果传入False表示删除该参数
# 例如无沙盒模式参数
co.set_argument("--no-sandbox")

# 删除浏览器内核启动参数,传入参数名即可
co.remove_argument("arg")

# 清空浏览器内核启动参数
co.clear_arguments()

# Chromium浏览器支持多用户配置,我们可以选择使用的用户配置,默认为Default
set_user("Default")

# 设置用户配置文件里的指定配置项set_pref("arg", "value")
# 隐藏是否保存密码的提示
co.set_pref("credentials_enable_service", False)

# 在当前配置对象中删除一个配置项,只能删该对象内配置的配置项
co.remove_pref("arg")

# 在用户配置文件删除一个配置项,可以删用户配置文件中存在的配置项
co.remove_pref_from_file("arg")

# 在当前配置对象中清空配置项
co.clear_prefs()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

# 使用配置

# 创建浏览器对象时指定配置对象即可
browser = Chromium(co)
1
2

# 浏览器连接

**Chromium**类用于连接和管理浏览器,标签页的开关和获取、整体运行参数配置、浏览器信息获取都由它进行。

同一进程中每个浏览器只能有一个Chromium对象,对同一个浏览器重复使用Chromium()获取的都是同一个对象。

在使用无头模式时需注意程序关闭后其实浏览器进程还在,只是看不见。

类的初始化参数:

  • addr_or_opts:浏览器启动配置或接管信息。

    如果传入IP:端口、浏览器WS地址、端口会按地址启动或接管浏览器。

    如果传入配置对象会按其配置启动或接管浏览器。

    如果为None会使用默认配置文件配置启动或接管浏览器。

# 直接连接浏览器

# 导入浏览器类
from DrissionPage import Chromium

# 使用默认配置,创建浏览器对象
browser = Chromium()
1
2
3
4
5

创建Chromium对象时会在指定端口启动浏览器,或接管该端口已有浏览器。

默认情况下,程序使用9222端口,浏览器可执行文件路径为"chrome"。

如路径中没找到浏览器可执行文件,Windows系统下程序会在注册表中查找路径,如果都没有则需要手动配置浏览器路径。

# 指定端口或地址连接浏览器

from DrissionPage import Chromium

# 接管9333端口的浏览器,如该端口空闲,启动一个浏览器
browser = Chromium(9333)

# 与上一行效果一样
browser = Chromium('127.0.0.1:9333')

# 指定ws连接
browser = Chromium('ws://127.0.0.1:8987/devtools/browser/3e590fc5-4587-47e1-8756-cf6784f2fef3')
1
2
3
4
5
6
7
8
9
10

按端口号或地址接管指定端口浏览器,若端口空闲,则使用默认配置在该端口启动一个浏览器。

# 按配置文件连接浏览器

from DrissionPage import Chromium, ChromiumOptions

# 创建启动配置对象
co = ChromiumOptions()

# 设置浏览器路径
co.set_browser_path("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")

# 指定启动配置创建浏览器对象,启动或接管浏览器
browser = Chromium(co)
1
2
3
4
5
6
7
8
9
10

# 浏览器对象

# 获取标签页

# latest_tab

返回最新的标签页对象或ID。

控制本地浏览器时,返回最后激活的标签页。

控制远程浏览器时,返回最后创建的标签页。

browser = Chromium()

# 单例模式下返回标签页对象,非单例模式时返回标签页ID
tab = browser.latest_tab
1
2
3
4

# get_tab()

获取匹配到的第一个标签页对象或标签页ID。

id_or_num为None时,条件查找参数才有效。

browser = Chromium()

# 获取列表中第一个标签页的对象
tab1 = browser.get_tab(1)
# 获取指定ID的标签页对象
tab2 = browser.get_tab('5399F4ADFE3A27503FFAA56390344EE5')
# 获取第一个url中带DrissionPage.cn的标签页对象
tab3 = browser.get_tab(url='DrissionPage.cn')
1
2
3
4
5
6
7
8

id_or_num:指定标签页ID或序号获取标签页对象,序号是激活顺序。

title:条件查找,模糊匹配title文本,默认为None,表示匹配所有。

url:条件查找,模糊匹配url文本,默认为None,表示匹配所有。

tab_type:条件查找,标签页类型,可用列表输入多个,如page(默认)、iframe等。

as_id:是否返回标签页ID而非对象,默认为False。

# get_tabs()

获取匹配到的所有标签页对象或标签页ID,会用列表包含并返回。

browser = Chromium()

# 获取所有url中带DrissionPage.cn的标签页对象
tabs = browser.get_tabs(url='DrissionPage.cn')
1
2
3
4

title:条件查找,模糊匹配title文本,默认为None,表示匹配所有。

url:条件查找,模糊匹配url文本,默认为None,表示匹配所有。

tab_type:条件查找,标签页类型,可用列表输入多个,如page(默认)、iframe等。

as_id:是否返回标签页ID而非对象,默认为False。

# 操作标签页

# new_tab()

新建标签页并返回标签页对象。

browser = Chromium()

# 新建标签页并跳转到指定URL
tab = browser.new_tab(url='https://www.baidu.com')
1
2
3
4

url:新建标签页时跳转的目标网址,默认为None,表示新建空白标签页。

new_window:是否在新窗口打开标签页,隐身模式下无效,默认为False。

background:是否不激活新标签页,隐身模式和访客模式及new_window为True时无效,默认为False。

new_context:是否创建独立环境,隐身模式和访客模式下无效,默认为False。

# activate_tab()

使一个标签页显示到前端,可传入标签页对象、标签页ID、标签页序号。

browser = Chromium()

# 使第一个标签页显示到前面
tab = browser.activate_tab(1)
1
2
3
4

# close_tabs()

关闭标签页,可指定多个,也可关闭指定标签页以外的标签页。

browser = Chromium()

# 关闭单个标签页
browser.close_tabs(browser.get_tab(1))
# 关闭多个标签页
browser.close_tabs([browser.get_tab(i) for i in range(3)])
# 关闭除指定标签页之外的所有标签页
browser.close_tabs(browser.get_tab(1), True)
1
2
3
4
5
6
7
8

tabs_or_ids:标签页对象或标签页ID,多个可用列表或元组传入。

others:是否关闭指定标签页之外的,默认为False。

# 浏览器信息

browser = Chromium()

# 返回浏览器默认下载路径
browser.download_path

# 返回浏览器进程PID
browser.process_id

# 返回浏览器是否仍可用
browser.states.is_alive

# 返回浏览器是否接管的,而非本程序创建的
browser.states.is_existed

# 返回浏览器是否无头模式
browser.states.is_headless

# 返回浏览器是否无痕模式
browser.states.is_incognito

# 返回浏览器所有域名的Cookies
# all_info参数:是否返回所有内容,默认False,只返回name、value、domain
browser.cookies(False)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 浏览器操作

browser = Chromium()

# 设置一个或多个cookie,需要带上domain属性
# 支持CookieJar、Cookie、list、tuple、str、dict等多种格式
browser.set.cookies({"name": "test", "value": "test", "domain": "test.cn"})

# 阻塞直到新标签页出现,可指定超时时间
browser.wait.new_tab()

# 阻塞直到浏览器一个下载任务开始,可指定超时时间
browser.wait.download_begin()

# 阻塞直到浏览器所有下载任务完成,可指定超时时间
browser.wait.downloads_done()

# 清除浏览器所有的Cookies
browser.set.cookies.clear()

# 清除浏览器缓存
browser.clear_cache()

# 关闭浏览器
browser.quit()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 标签页对象

# 标签页设置

tab = browser.latest_tab

# 单独设置页面的加载模式为normal
tab.set.load_mode.normal()

# 单独设置页面的加载模式为eager
tab.set.load_mode.eager()

# 单独设置页面的加载模式为none
tab.set.load_mode.none()
1
2
3
4
5
6
7
8
9
10

# 标签页模式

MixTab和WebPage有两种模式,d模式用于控制浏览器,s模式用于通过requests收发数据包。两种模式共用同一套API,但共用的API其操作对象不同。

每个标签页对象创建时都处于d模式。

d模式下ele()方法的查找对象是浏览器的标签页,s模式下是requests的结果。

因此s模式下要控制浏览器,只能调用d模式独有的功能。另外切换模式前已获取的元素对象仍可继续操作。

使用tab.change_mode()方法可以进行切换,模式切换的时候会同步登录信息。

切换到s模式后,如不再需要浏览器,可以用close()或quit()方法关闭标签页或浏览器。标签页对象可继续用于收发数据包。

tab = browser.latest_tab

# 默认是d模式
tab.get('http://DrissionPage.cn')

# 返回当前模式字符串"d"或"s"
tab.mode

# 切换模式
# mode:传入's'或'd'可以切换到指定模式,为None则切换到另一个模式
# go:切换时是否跳转到原模式的URL,默认为True
# copy_cookies:切换时是否复制Cookies,默认为True
tab.change_mode()
1
2
3
4
5
6
7
8
9
10
11
12
13

# 标签页请求

# get()

使标签页跳转到指定网址。

返回布尔类型,以表示是否成功访问。

tab = browser.latest_tab

tab.get("https://www.baidu.com")
1
2
3
参数名称 类型 默认值 说明
url str 必填 目标URL,可指向本地文件路径。
show_errmsg bool False 连接出错时是否显示和抛出异常。
retry int None 重试次数,为None时使用页面参数,默认3。
interval float None 重试间隔(秒),为None时使用页面参数,默认2。
timeout float None 加载超时时间(秒)

s模式参数

参数名称 类型 默认值 说明
params dict None url 请求参数。
data dict str None 携带的数据。
json dict str None 要发送的 JSON 数据,会自动设置 Content-Type 为'application/json'。
headers dict None 请求头。
cookies dict CookieJar None cookies 信息。
files Any None 要上传的文件,可以是一个字典,其中键是文件名,值是文件对象或文件路径。
auth Any None 身份认证信息。
allow_redirects bool True 是否允许重定向。
proxies dict None 代理信息。
hooks Any None 回调方法。
stream bool None 是否使用流式传输。
verify bool str None 是否验证 SSL 证书。
cert str Tuple[str, str] None SSL 客户端证书文件的路径(.pem 格式),或('cert', 'key')元组。

# post()

使用内置的Session对象以POST方式发送请求。

返回请求结果的Response对象。

因为post()是使用requests的post()方法发送请求,所以参数和用法与requests一致。

参数同上面get()方法的参数完全一致,且不区分s模式。

# 标签页信息

tab = browser.latest_tab

# 返回当前页面html文本
tab.html

# 把页面内容解析成json
tab.json

# 返回当前页面title文本
tab.title

# 返回当前页面UserAgent信息
tab.user_agent

# 返回当前访问的URL
tab.url

# 返回当前标签页的ID
tab.tab_id

# 返回页面是否正在加载状态
tab.states.is_loading

# 返回页面当前加载状态
# connecting: 网页连接中
# loading:表示文档还在加载中
# interactive:DOM 已加载,但资源未加载完成
# complete:所有内容已完成加载
tab.states.ready_state

# 返回页面是否存在弹出框
tab.states.has_alert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 标签页操作

tab = browser.latest_tab

# 在浏览历史中后退若干步,默认为1步
tab.back(1)

# 在浏览历史中前进若干步,默认为1步
tab.forward(1)

# 刷新当前页面
tab.refresh()

# 强制停止当前页面加载
tab.stop_loading()

# 关闭与页面连接,然后重建一个新连接,断开连接可释放内存
tab.reconnect()

# 关闭标签页
tab.close()

# 阻塞直到页面进入加载状态
tab.wait.load_start()

# 阻塞直到页面文档加载完成
tab.wait.doc_loaded()

# 阻塞直到指定元素被加载到DOM,成功则返回
# 可指定元素对象或定位符,可用列表等待多个
tab.wait.eles_loaded("#test")

# 阻塞直到指定元素已加载并变成显示状态
# 可指定元素对象或定位符,可用列表等待多个
tab.wait.ele_displayed("#test")

# 阻塞直到指定元素已加载变成隐藏状态
# 可指定元素对象或定位符,可用列表等待多个
tab.wait.ele_hidden("#test")

# 阻塞直到一指定元素从DOM中被删除
# 可指定元素对象或定位符,可用列表等待多个
tab.wait.ele_deleted("#test")

# 阻塞直到标题变成包含或不包含指定文本
# text:用于识别的文本
# exclude:是否排除,默认为False
tab.wait.title_change("test")

# 阻塞直到URL变成包含或不包含指定文本
# text:用于识别的文本
# exclude:是否排除,默认为False
tab.wait.url_change("test")

# 等待弹出框被关闭
tab.wait.alert_closed()

# 对页面或元素进行截图,可对整个网页、可见网页、指定范围截图
# 还可指定截图保存到本地、返回bytes、返回base64
tab.get_screenshot(path='./tmp/', name='pic.jpg', full_page=True)


# 把当前页面保存为文件,同时返回保存的内容
# 如果path和name参数都为None,则只返回内容
tab.save("path", "name")

# 忽略指定URL的连接
# 可使用元组或列表传入多个,可用*通配符,传入None时清空已设置的项
tab.blocked_urls('*.css*')



# 设置标签页Cookie
tab.set.cookies()
# 清除标签页所有Cookies
tab.set.cookies.clear()
# 删除标签页指定cookie
tab.set.cookies.remove()
# 清除标签页缓存
tab.clear_cache()

# 使窗口最大化
tab.set.window.max()
# 使窗口最小化
tab.set.window.mini()
# 使窗口切换到全屏模式
tab.set.window.full()
# 设置窗口大小到指定大小,整数类型
tab.set.window.size(宽度, 高度)
# 设置窗口位置
tab.set.window.location(水平位置, 垂直位置)
# 隐藏当前浏览器窗口
tab.set.window.hide()
# 显示当前浏览器窗口
tab. set.window.show()

# 向下滚动若干像素
tab.scroll.down(滚动像素)
# 向上滚动若干像素
tab.scroll.up(滚动像素)
# 滚动页面到顶部位置
tab.scroll.to_top()
# 滚动页面到垂直居中位置
scroll.to_half()
# 滚动页面到底部位置
tab.scroll.to_bottom()
# 滚动页面指定位置
tab.scroll.to_location(水平位置, 垂直位置)
# 滚动页面直到元素可见
# loc_or_ele:元素的定位信息,可以是元素、定位符
# center:是否尽量滚动到页面正中,默认为None,表示如果被遮挡则滚动到页面正中
tab.scroll.to_see(None)

# 是否开启平滑滚动,建议用此方法为网页关闭平滑滚动,默认True
tab.set.scroll.smooth(True)

# 处理提示框
# accept:True表示确认(默认),False表示取消,None不会按按钮但依然返回文本值
# send:处理prompt提示框时输入指定文本
# timeout:等待提示框出现的超时时间(秒),为None时使用页面整体超时时间
# next_one:是否处理下一个出现的弹窗,为True时timeout参数无效
tab.handle_alert()

# 设置自动处理TAB的确认框
# on_off:是否开启,默认True
# accept:True表示确认(默认),False表示取消
tab.set.auto_handle_alert()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

# 动作链

动作链可以在浏览器上完成一系列交互行为,如鼠标移动、鼠标点击、键盘输入等,浏览器页面对象都支持使用动作链。

这些操作皆为模拟,真正的鼠标不会移动,因此可以多个标签页同时操作。

相关链接:https://drissionpage.cn/browser_control/actions

# 查找元素

# 定位符介绍

DrissionPage提供一套简洁易用的语法,用于快速定位元素,并且内置等待功能、支持链式查找,减少了代码的复杂性。

同时也兼容CSS选择器、Xpath和Selenium原生的loc元组。

# 函数方法

.ele():根据条件定位元素,返回匹配到的第一个元素对象。

.eles():根据条件定位元素,用列表返回匹配到的所有元素对象。

DrissionPage中所有页面对象和元素对象,都可以链式的在自己内部查找元素。元素对象还能以自己为基准,相对定位其它元素。

# 即可在Tab标签页对象中查找,也可以在Ele元素对象中查找。
tab.ele().ele()...
1
2

# 匹配符号

@单属性匹配符

单个@在只以一个属性作为匹配条件时使用,以'@'开头,后面跟属性名称。

# 例如查找包含id属性的元素
e = tab.ele("@id")
1
2

@@多属性与匹配符

当需要多个条件同时来确定一个元素时,每个属性用'@@'开头。

# 例如查找class为test并且文本为"hello"的元素
e = tab.ele("@@class=test@@text()=hello")
1
2

@|多属性或匹配符

当需要以或关系条件查找元素时,每个属性用'@|'开头。

# 例如查找id为one或two的元素
e = tab.ele("@|id=one@|id=two")
1
2

@!否定匹配符

当需要通过条件否定排除元素时,可以使用'@!'匹配符。

可与@@和@|混合使用。

# 获取第一个ID不等于one的元素
ele = tab.ele("@!id=one")

# 匹配class等于test并且id不等于one的元素
tab.ele("@@class=test@!id=one")
1
2
3
4
5

注意

@@和@|不能同时出现的查找语句中,即一个查找语句只能是与关系或者或关系。

如果匹配文本或属性中出现@@、@|、@!等字符串时,不能使用多属性匹配,需改用xpath的方式。

# 匹配模式

匹配模式指某个查询中匹配条件的方式,有精确匹配、模糊匹配、匹配开头、匹配结尾四种。

=精确匹配

:模糊匹配

^匹配开头

$匹配结尾

# 使用方法

# 通过元素名定位,只有语句放在条件最前面时生效
# "tag:标签名"、"tag=标签名"、"@tag()=标签名"效果一致
e = tab.ele("tag:div")

# 通过元素ID定位,"@id=元素ID"
# 可以简写为"#ID",但只在语句最前面且单独使用时生效
e = tab.ele("#one")

# 通过元素属性定位,"@属性名"、"@属性名=值"
e = tab.ele("@name")
e = tab.ele("@name=hello")

# 通过元素文本定位,"@text()=文本"
# 可简写为"文本"、"text:文本"、"text=文本",但只语句在最前面且单独使用时生效
e = tab.ele("我是文本")

# 通过CSS选择器来匹配
# "css=语法"与"css:语法"效果一致
e = tab.ele("css=.div")

# 通过xpath匹配
# "xpath=语法"与"xpath:语法"效果一致
e = tab.ele('xpath://div')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 元素对象

# 元素相对定位

DrissionPage支持按照条件获取元素对象的直接子节点、同级节点、祖先元素、文档前后节点等。

# 获取父级节点
# 可以指定第几级父节点,或者用定位符在祖先节点中进行筛选
e.parent(3) # 获取第三个父级标签
e.parent("tag:p") # 获取父级第一个p标签
e.parent("tag:p", 3) # 获取父级第三个p标签

# 获取直接子节点
# 可以指定第几级子节点,或者用定位符在子节点中进行筛选
e.child("tag:p")

# 获取所有符合条件的子节点
e.children("tag:p")

# 返回当前元素前面或后面的某一个同级节点
# 可以指定第几个元素,或者用定位符在前面或后面同级节点中进行筛选
e.prev("tag:p")
e.next("tag:p")


# 获取当前元素前面或后面所有符合条件的同级节点
e.prevs("tag:p")
e.nexts("tag:p")

# 返回当前元素前面或后面的某一个节点(不限同级)
e.before("tag:p")
e.after("tag:p")

# 获取当前元素前面或后面所有符合条件的节点(不限同级)
e.befores("tag:p")
e.afters("tag:p")


# 前面是基于DOM的相对定位方式,DrissionPage还支持基于视觉相对定位,但需要在浏览器模式下才支持
# 获取当前元素上下左右的可见元素,可用像素距离或者定位符来筛选
e.north(30) # 上
e.south(30) # 下
e.west(30) # 左
e.east(30) # 右
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 元素交互

# 左键点击元素,可选择模拟点击或JS点击,可简化为e.click()
# by_js:为None时,如果元素被遮挡用JS点击,否则用模拟点击。为True时用JS点击,为False时被遮挡也会强制模拟点击(默认)
e.click()
e.click.left()

# 右键点击元素
e.click.right()

# 中键点击元素,默认返回新出现的Tab对象
e.click.middle()

# 多次左键点击元素,可指定次数,默认2次
e.click.multi()

# 带偏移量点击元素,偏移量相对于元素左上角坐标
# x,y:相对元素左上角坐标的x和y轴偏移量,向下向右为正
# button:要点击的键,传入'left'、'right'、'middle'、'back'、'forward'
# count:点击次数
e.click.at(50, -50) # 点击元素右上方 50*50 的位置
e.click.at(offset_x=50) # 点击元素上中部,x相对左上角向右偏移50,y保持在元素中点

# 用于点击文件选择框元素,并把指定的文件路径添加到网页
e.click.to_upload("文件路径")

# 点击元素并等待新Tab对象返回
e.click.for_new_tab()

# 用于清空元素文本
# by_js:是否用JS方式清空,默认为False
# 模拟按键方式会自动输入ctrl-a-del组合键来清除文本框,JS方式则直接把元素value属性设置为空
e.clear()

# 向元素输入文本或组合键,也可用于输入文件路径到上传控件
# vals:文本值或按键组合
# clear:输入前是否清空文本框,默认为False
# by_js:是否用JS方式输入,为True时不能输入组合键,默认为False
e.input("hello")

# 使用组合键或要传入特殊按键时,要导入按键类Keys
from DrissionPage.common import Keys
e.input(Keys.CTRL_A) # 常用组合键
e.input((Keys.CTRL, 'a', Keys.DEL)) # 自定义组合键

# 使元素获取焦点
e.focus()

# 拖拽元素到相对于当前的一个新位置,坐标向下向右为正,可以设置速度
# e.drag(x, y, 拖动用时(秒))
e.drag(50, 50, 1) # # 拖动当前元素到距离50*50的位置,用时1秒

# 拖拽元素到另一个元素上或一个网页坐标上
# e.drag_to(另一个元素对象或网页坐标元组, 拖动用时(秒))
e1.drag_to(e2) # 把e1拖拽到e2上
e1.drag_to((50, 50)) # 把e1拖拽到网页50,50的位置

# 模拟鼠标悬停在元素上,默认停留在元素中心
# 可接受偏移量,偏移量相对于元素左上角坐标,向下向右为正
e.hover(x, y)

# 设置元素属性
e.set.attr("name", "value")

# 删除元素属性
e.remove_attr("name")

# 设置元素value值
e.set.value("value")

# 选中或取消选中元素
# uncheck:是否取消选中,默认为False
# by_js:是否用JS方式选择,默认为False
e.check()

# 元素滚动
e.scroll.to_top() # 滚动到顶部
e.scroll.to_bottom() # 滚动到底部
e.scroll.to_leftmost() # 滚动到最左边
e.scroll.to_rightmost() # 滚动到最右边
e.scroll.up() # 向上滚动 200 像素
e.scroll.down(200) # 向下滚动 200 像素
e.scroll.to_location(100, 300) # 滚动到指定位置
e.scroll.to_see() # 滚动页面使自己可见

# 按文本/Value属性/序号/定位符/元素对象来选择列表项,传入列表可选择多项
e.select.by_text("male") # 按文本,可简写为select()
e.select.by_value("male") # 按Value值
e.select.by_index(3) # 按序号
select.by_locator("#optone") # 按定位符
e.select.by_option(optele) # 按元素对象

# 按文本/Value属性/序号/元素对象来取消选择列表项,传入列表可取消选择多项
e.select.cancel_by_text("male") # 按文本
e.select.cancel_by_value("male") # 按Value值
e.select.cancel_by_index(3) # 按序号
e.select.cancel_by_locator("#optone") # 按定位符
e.select.cancel_by_option(optele) # 按元素对象

# 全选所有项,多选列表才有效
e.select.all()

# 取消所有项选中状态,多选列表才有效
e.select.clear()

# 反选,多选列表才有效
e.select.invert()

# 返回当前列表元素所有选项元素对象
e.select.options

# 返回当前元素选中的选项(单选列表)
e.select.selected_option

# 当前元素所有选中的选项(多选列表)
e.select.selected_options
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

# 元素信息

# 返回元素的标签名
e.tag

# 返回元素的HTML文本
e.html

# 返回元素内所有文本组合成的字符串
e.text

# 返回元素内未经处理的原始文本
e.raw_text

# 返回元素内所有直接子节点的文本,包括元素和文本节点
e.texts()

# 以列表形式返回元素内的注释
e.comments

# 以字典形式返回元素所有属性及值
e.attrs

# 返回元素指定属性名的值
e.attr("name")

# 返回元素的Value值
e.value

# 返回元素href属性或src属性的值,没有则返回None
e.link

# 以元组形式返回元素左上角在整个页面中的坐标
e.rect.location

# 以元组形式返回click()元素点击点在整个页面中的坐标,位于元素中上部
e.rect.click_point

# 以布尔值方式返回元素是否在视口中可被点击
e.states.is_in_viewport

# 以布尔值方式返回元素是否整个显示在视口中
e.states.is_whole_in_viewport

# 返回元素是否可被模拟点击,从是否有大小、是否可用、是否显示、是否响应点击判断,不判断是否被遮挡
states.is_clickable

# 以布尔值形式返回当前元素是否仍可用,用于判断d模式下是否因页面刷新而导致元素失效
e.states.is_alive

# 以布尔值返回表单单选或多选元素是否选中
e.states.is_checked

# 以布尔值返回Select元素中的项是否选中
e.states.is_selected

# 以布尔值返回元素是否可见
e.states.is_displayed

# 返回当前元素在页面中Xpath的绝对路径
e.xpath

# 返回当前元素在页面中CSS选择器的绝对路径
e.css_path

# 元素列表批量获取信息
# 通过eles()返回的列表,可以调用get属性的方法来批量获取指定信息
eles('tag:a').get.texts()
eles('tag:a').get.attrs()
eles('tag:a').get.links()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# 使用例子

# 自动注册某网站

import time
import random

from DrissionPage import Chromium, ChromiumOptions

# 创建启动配置对象
co = ChromiumOptions()

# 设置浏览器路径
co.set_browser_path("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")

# 设置总是打开新浏览器
co.auto_port()

# 设置无痕模式
co.incognito()

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

# 跳转到三毛机场注册网址
tab = browser.latest_tab
tab.get("https://g-1.smjcdh.top/#/register")

# 点击进入按钮
tab.ele("#setCookieBtn").click()
print(f"正在进入注册网址...")

# 随机邮箱、密码
email = "".join([str(random.randint(0, 9)) for i in range(10)]) + "@qq.com"
passwd = "qwe" + "".join([str(random.randint(0, 9)) for i in range(6)])
print(f"生成账号密码:{email}----{passwd}")

# 输入邮箱、密码
tab.ele("@placeholder=邮箱").input(email)
[i.input(passwd) for i in tab.eles("@|placeholder=密码@|placeholder=再次输入密码")]

# 点击注册,有验证所以需要模拟动作链
time.sleep(random.randint(1, 2))
regist_ele = tab.ele("@@class=n-button__content@@text():注册").click()

# 判断是否注册成功
if tab.ele(".=n-message__content").text == "注册成功":
    print("注册成功!")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 自动爬取京东商品信息

import re
import time
from urllib.parse import quote
from DrissionPage import Chromium, ChromiumOptions

keyword = "椅子"

search_url = f"https://search.jd.com/Search?keyword=" + quote(keyword)

# 创建启动配置对象
co = ChromiumOptions()

# 设置浏览器路径
co.set_browser_path("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")

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

# 跳转到京东进行登录
tab = browser.latest_tab


def log(text):
    print(f'[{time.strftime("%Y-%m-%d %H:%M:%S")}] {text}')


def login():
    tab.get("https://www.jd.com/")
    # 等待1秒如果没有跳转到登录页面,并且未登录则点击登录按钮
    time.sleep(1)
    if tab.title == "京东-欢迎登录":
        log("已自动跳转到登录界面,等待用户登录")
    elif tab.ele("@class=link-login", timeout=0):
        tab.ele("@class=link-login").click()
        log("未自动跳转到登录界面,已点击打开登录框并等待用户登录")

    # 等待5分钟用户登录
    if tab.wait.eles_loaded("@class=nickname", timeout=300):
        log("用户已登录")
    else:
        log("用户登录超时,请重新运行程序")
        quit()


def jump_scroll(page_num):
    # 判断是否已在检索页面检索,不在则跳转
    if not tab.url.startswith(search_url):
        tab.get(search_url)
        log("已跳转到检索页面")

    # 如果未按销量排序,则单击按销量进行排序
    sort_ele = tab.eles("@@class^_sort-tag-inner").filter_one.text("销量").parent()
    if "_sort-tag-button__active" not in sort_ele.attr("class"):
        sort_ele.click()
        log("已按销量进行排序")

    # 跳转到指定页数
    tab.ele("@class^_pagination_toPageNum").ele("tag=input").input(str(page_num) + "\n")
    log(f"已转到第 {page_num} 页")

    # 等待加载
    time.sleep(0.2)
    tab.wait.eles_loaded("@class^_goodsContainer")

    # 滚动直到能看到分页器
    tab.set.scroll.smooth(True)
    pagele = tab.ele("@class^_pagiContainer")
    log("正在进行滚动...")
    while not pagele.states.is_whole_in_viewport:
        tab.scroll.down(800)
    log("滚动完毕!")


def scrapy_page_data():
    log("开始爬取数据...")
    # 获取商品信息
    card_eles = tab.ele("@class^_goodsContainer").children("@_card^")
    for i in card_eles:
        title = i.ele("@class^_goods_title").ele("@title").text
        selling_point = set(re.split("[\n|]", i.ele("@class^_goods_title").next().text))
        volume = [v.attr("title") for v in i.ele("@class^_goods_volume").eles("@title")]
        shop_name = i.ele("@class^_shopFloor").text
        data = {"title": title, "selling_point": list(selling_point), "volume": volume, "shop_name": shop_name}
        print(data)


if __name__ == "__main__":
    login()
    for page in range(3):
        jump_scroll(page + 1)
        scrapy_page_data()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#爬虫#DrissionPage#网页自动化
Xpath模块
JS逆向基础

← Xpath模块 JS逆向基础→

最近更新
01
Vue路由
12-09
02
FastAPI实现用户管理
11-23
03
Tortoise ORM
11-23
更多文章>
Theme by Vdoing | Copyright © 2022-2026 Hoshinozora | MIT License
湘ICP备2022022820号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式