mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
大量更新文档
This commit is contained in:
parent
b5892c622b
commit
82c4140fff
@ -1,50 +1,60 @@
|
||||
# v3.1.3
|
||||
|
||||
- `ChromiumPage`添加`latest_tab`属性
|
||||
|
||||
- `WebPage`初始化删除`tab_id`参数
|
||||
|
||||
- 修复页面未加载完可能获取到空元素的问题
|
||||
|
||||
- 修复新标签页重定向时获取文档不正确问题
|
||||
|
||||
- 增强稳定性
|
||||
|
||||
# v3.1.1
|
||||
|
||||
- 增强下载功能
|
||||
|
||||
- `ChromiumPage`也可以使用内置下载器下载文件
|
||||
- `ChromiumPage`也可以使用内置下载器下载文件
|
||||
|
||||
- 可拦截并接管浏览器下载任务
|
||||
- 可拦截并接管浏览器下载任务
|
||||
|
||||
- 新增`download_set`属性对下载参数进行设置
|
||||
- 新增`download_set`属性对下载参数进行设置
|
||||
|
||||
- 增加`wait_download_begin()`方法
|
||||
|
||||
- 重构部分代码
|
||||
- 增加`wait_download_begin()`方法
|
||||
|
||||
- 改进浏览器启动设置
|
||||
|
||||
- 优化 ini 文件结构
|
||||
- 优化 ini 文件结构
|
||||
|
||||
- 新增`ChromiumOptions`取代`DriverOptions`,完全摆脱对 selenium 的依赖
|
||||
- 新增`ChromiumOptions`取代`DriverOptions`,完全摆脱对 selenium 的依赖
|
||||
|
||||
- 新增自动分配端口功能
|
||||
- 新增自动分配端口功能
|
||||
|
||||
- 优化`SessionOptions`设计,增加一系列设置参数的方法
|
||||
- 优化`SessionOptions`设计,增加一系列设置参数的方法
|
||||
|
||||
- 改进对用户配置文件的设置
|
||||
- 改进对用户配置文件的设置
|
||||
|
||||
- 对部分代码进行重构
|
||||
|
||||
- 优化页面对象启动逻辑
|
||||
- 优化页面对象启动逻辑
|
||||
|
||||
- 优化配置类逻辑
|
||||
- 优化配置类逻辑
|
||||
|
||||
- 优化项目结构
|
||||
- 优化项目结构
|
||||
|
||||
- 细节
|
||||
|
||||
- 上传文件时支持传入相对路径
|
||||
- 上传文件时支持传入相对路径
|
||||
|
||||
- bug 修复
|
||||
|
||||
- 修复`get_tab()`出错问题
|
||||
- 修复`get_tab()`出错问题
|
||||
|
||||
- 修复新浏览器第一次新建标签页时不正确切换的问题
|
||||
- 修复新浏览器第一次新建标签页时不正确切换的问题
|
||||
|
||||
- 修复关闭当前标签页出错问题
|
||||
- 修复关闭当前标签页出错问题
|
||||
|
||||
- 修复改变浏览器窗口大小出错问题
|
||||
- 修复改变浏览器窗口大小出错问题
|
||||
|
||||
# v3.0.34
|
||||
|
||||
@ -129,8 +139,8 @@
|
||||
# v2.7.1
|
||||
|
||||
- DriverPage
|
||||
- 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法
|
||||
- `run_cdp()`的`cmd_args`参数改为`**cmd_args`
|
||||
- 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法
|
||||
- `run_cdp()`的`cmd_args`参数改为`**cmd_args`
|
||||
- 关闭 driver 时会主动关闭 chromedriver.exe 的进程
|
||||
- 优化关闭浏览器进程逻辑
|
||||
|
||||
@ -142,9 +152,9 @@
|
||||
# v2.6.0
|
||||
|
||||
- 新增`Listener`类
|
||||
- 可监听浏览器数据包
|
||||
- 可异步监听
|
||||
- 可实现每监听到若干数据包执行操作
|
||||
- 可监听浏览器数据包
|
||||
- 可异步监听
|
||||
- 可实现每监听到若干数据包执行操作
|
||||
- 放弃对selenium4.1以下的支持
|
||||
- 解决使用新版浏览器时出现的一些问题
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
- 设置页面加载时限及加载策略。有时不需要完整加载页面资源,可根据实际须要设置加载策略。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 自动重试连接
|
||||
|
||||
在访问网站时,由于网络不稳定可能导致连接异常。本库设置了连接自动重试功能,当网页连接异常,会默认重试 3 次。当然也可以手动设置次数和间隔。
|
||||
@ -24,6 +26,8 @@
|
||||
page.get('xxxxxx', retry=5, interval=3) # 出错是重试 5 次,每次间隔 3 秒
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 极简的定位语法
|
||||
|
||||
本库制定了一套简洁高效的查找元素语法,支持链式操作,支持相对定位。与 selenium 繁琐的语法相比简直不要太方便。
|
||||
@ -40,6 +44,8 @@ element = WebDriverWait(driver, 10).until(ec.presence_of_element_located((By.XPA
|
||||
element = page('some text', timeout=10)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 无需切入切出,逻辑清晰
|
||||
|
||||
使用过 selenium 的人都知道,selenium 同一时间只能操作一个标签页或`<iframe>`元素,要操作其它标签页,或`<iframe>`元素,须要用`switch_to()`
|
||||
@ -70,10 +76,14 @@ tab1.get('https://www.baidu.com')
|
||||
tab2.get('https://www.163.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 高度集成的便利功能
|
||||
|
||||
很多操作方法集成了常用功能,如`chick()`中内置`by_js`参数,可以直接改用 js 方式点击,而无需写独立的 js 语句。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 强大的下载功能
|
||||
|
||||
DrissionPage 内置一个下载工具,可实现大文件分块多线程下载文件。并且可以直接读取缓存数据保存图片,而无需控制页面作另存操作。
|
||||
@ -83,6 +93,8 @@ img = page('tag:img')
|
||||
img.save('img.png') # 直接保存图片到文件夹
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 更多便捷的功能
|
||||
|
||||
- 可对整个网页截图,包括视口外的部分
|
@ -1,6 +1,6 @@
|
||||
以下代码实现一模一样的功能,对比两者的代码量:
|
||||
|
||||
## 获取元素内容
|
||||
🔸 获取元素内容
|
||||
|
||||
```python
|
||||
url = 'https://baike.baidu.com/item/python'
|
||||
@ -21,7 +21,7 @@ title = page('tag:h1').text
|
||||
|
||||
?> **Tips:** <br>DrissionPage 自带默认 headers
|
||||
|
||||
## 下载文件
|
||||
🔸 下载文件
|
||||
|
||||
```python
|
||||
url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
|
@ -1,6 +1,6 @@
|
||||
以下代码实现一模一样的功能,对比两者的代码量:
|
||||
|
||||
## 用显性等待方式查找第一个文本包含 some text 的元素。
|
||||
🔸 用显性等待方式查找第一个文本包含 some text 的元素。
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -10,7 +10,7 @@ element = WebDriverWait(driver).until(ec.presence_of_element_located((By.XPATH,
|
||||
element = page('some text')
|
||||
```
|
||||
|
||||
## 跳转到第一个标签页
|
||||
🔸 跳转到第一个标签页
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -20,7 +20,7 @@ driver.switch_to.window(driver.window_handles[0])
|
||||
page.to_tab(0)
|
||||
```
|
||||
|
||||
## 按文本选择下拉列表
|
||||
🔸 按文本选择下拉列表
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -32,7 +32,7 @@ select_element.select_by_visible_text('text')
|
||||
element.select('text')
|
||||
```
|
||||
|
||||
## 拖拽一个元素
|
||||
🔸 拖拽一个元素
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -42,7 +42,7 @@ ActionChains(driver).drag_and_drop(ele1, ele2).perform()
|
||||
ele1.drag_to(ele2)
|
||||
```
|
||||
|
||||
## 滚动窗口到底部(保持水平滚动条不变)
|
||||
🔸 滚动窗口到底部(保持水平滚动条不变)
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -52,7 +52,7 @@ driver.execute_script("window.scrollTo(document.documentElement.scrollLeft, docu
|
||||
page.scroll.to_bottom()
|
||||
```
|
||||
|
||||
## 设置 headless 模式
|
||||
🔸 设置 headless 模式
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -63,7 +63,7 @@ options.add_argument("--headless")
|
||||
set_headless(True)
|
||||
```
|
||||
|
||||
## 获取伪元素内容
|
||||
🔸 获取伪元素内容
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
@ -73,7 +73,7 @@ text = webdriver.execute_script('return window.getComputedStyle(arguments[0], ":
|
||||
text = element.pseudo_after
|
||||
```
|
||||
|
||||
## 获取 shadow-root
|
||||
🔸 获取 shadow-root
|
||||
|
||||
新版 selenium 已可直接获取 shadow-root,但生成的 ShadowRoot 对象功能实在是太少了。
|
||||
|
||||
@ -85,7 +85,7 @@ shadow_element = webdriver.execute_script('return arguments[0].shadowRoot', elem
|
||||
shadow_element = element.shadow_root
|
||||
```
|
||||
|
||||
## 用 xpath 直接获取属性或文本节点(返回文本)
|
||||
🔸 用 xpath 直接获取属性或文本节点(返回文本)
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
@ -1,4 +1,4 @@
|
||||
用 selenium 登录网站,然后切换到 requests 读取网页。两者会共享登录信息。
|
||||
用浏览器登录网站,然后切换到 requests 读取网页。两者会共享登录信息。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
@ -20,8 +20,8 @@ page.change_mode()
|
||||
print('登录后title:', page.title, '\n')
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```shell
|
||||
```console
|
||||
登录后title: 个人资料 - 码云 Gitee.com
|
||||
```
|
@ -13,9 +13,9 @@ text = page('@id:footer-left')('css:>div')('text:命令学').text
|
||||
print(text)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```shell
|
||||
```console
|
||||
Git 命令学习 https://oschina.gitee.io/learn-git-branching/
|
||||
|
||||
Git 命令学习
|
@ -6,20 +6,26 @@ python 版本:3.6 及以上
|
||||
|
||||
支持浏览器:Chromium 内核(如 Chrome 和 Edge)
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 安装
|
||||
|
||||
请使用 pip 安装 DrissionPage:
|
||||
|
||||
```shell
|
||||
```console
|
||||
pip install DrissionPage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 升级
|
||||
|
||||
```shell
|
||||
```console
|
||||
pip install DrissionPage --upgrade
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 导入
|
||||
|
||||
## 📍 页面类
|
||||
@ -44,6 +50,8 @@ from DrissionPage import ChromiumPage
|
||||
from DrissionPage import SessionPage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 配置类
|
||||
|
||||
很多时候我们须要设置启动参数,可导入以下两个类,但不是必须的。
|
||||
@ -60,6 +68,8 @@ from DrissionPage import ChromiumOptions
|
||||
from DrissionPage import SessionOptions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 其它工具
|
||||
|
||||
有两个我们可能须要用到的工具,需要时可以导入。
|
||||
@ -81,3 +91,20 @@ from DrissionPage import Keys
|
||||
```python
|
||||
from DrissionPage.easy_set import *
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 旧版页面和配置类
|
||||
|
||||
旧版`MixPage`是基于 selenium 封装而成,使用方法与`WebPage`一致。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
```
|
||||
|
||||
旧版配置类:
|
||||
|
||||
```python
|
||||
from DrissionPage import DriverOptions
|
||||
from DrissionPage import Drission
|
||||
```
|
@ -16,6 +16,8 @@
|
||||
|
||||
!>**注意:**<br>如果您使用的是 Edge 浏览器,直接关闭不能清干净进程,请打开任务管理器手动关闭进程。
|
||||
|
||||
---
|
||||
|
||||
## 📍 尝试启动浏览器
|
||||
|
||||
执行以下代码,如果正常启动了浏览器并且访问了百度,说明可直接使用,跳过后面的步骤即可。
|
||||
@ -27,6 +29,8 @@ page = ChromiumPage()
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 设置路径
|
||||
|
||||
如果上面的步骤提示出错,请新建一个临时 py 文件,并输入以下代码,填入您电脑里的 Chrome 浏览器 exe 文件路径,然后执行。
|
||||
@ -41,10 +45,14 @@ set_paths(browser_path=r'这里修改为您的Chrome浏览器exe文件路径')
|
||||
|
||||
这段代码会记录 Chrome 浏览器路径到配置文件。
|
||||
|
||||
---
|
||||
|
||||
## 📍 重试控制浏览器
|
||||
|
||||
现在,请重新执行第二步的代码,如果正确访问了百度,说明已经设置完成。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 说明
|
||||
|
||||
当您完成准备工作后,无须关闭浏览器,后面的上手示例可继续使用当前浏览器。
|
@ -16,6 +16,8 @@
|
||||
|
||||
我们可以用这三个属性定位这三个元素,然后对其输入数据和点击。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
您可以把以下代码复制到编辑器,把账号和密码改为您自己的,可直接执行看到运行结果。
|
||||
@ -38,6 +40,8 @@ page.ele('#user_password').input('您的密码')
|
||||
page.ele('@value=登 录').click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例详解
|
||||
|
||||
我们逐行解读代码:
|
@ -18,6 +18,8 @@
|
||||
|
||||
同时,我们观察到,列表页网址是以页数为参数访问的,如第一页 url 为`https://gitee.com/explore/all?page=1`,页数就是`page`参数。因此我们可以通过修改这个参数访问不同的页面。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
以下代码可直接运行并查看结果:
|
||||
@ -40,7 +42,7 @@ for i in range(1, 4):
|
||||
print(link.text, link.link)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
小熊派开源社区/BearPi-HM_Nano https://gitee.com/bearpi/bearpi-hm_nano
|
||||
@ -51,6 +53,8 @@ TopIAM/eiam https://gitee.com/topiam/eiam
|
||||
以下省略。。。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例详解
|
||||
|
||||
我们逐行解读代码:
|
@ -24,6 +24,8 @@
|
||||
|
||||
通过分析 html 代码,我们可以看出,每个结果的标题都存在于`<h3>`元素里。因此,我们可以获取页面中所有`<h3>`元素,再遍历获取其信息。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
您可以直接运行以下代码:
|
||||
@ -49,7 +51,7 @@ for link in links:
|
||||
print(link.text)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
DrissionPage: 一个整合了selenium和requests_html的模块,...
|
||||
@ -64,6 +66,8 @@ DrissionPagev1.10.0 已经发布,WEB 自动化测试集成工具 |...
|
||||
DrissionPagev2.2.1 发布,WEB 自动化测试集成工具
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例详解
|
||||
|
||||
我们逐行解读代码:
|
@ -18,10 +18,20 @@
|
||||
|
||||
如果您想了解旧版,请查阅“旧版使用方法”章节。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 主要对象
|
||||
|
||||
无论是控制浏览器,还是收发数据包,其操作逻辑是一致的,即先创建页面对象,通过页面对象控制浏览器或收发数据包,再从浏览器或返回的数据中获取元素对象,从而实现数据的获取或页面的控制。因此,最主要的对象就是两种:页面对象,及其生成的元素对象。
|
||||
|
||||
常用的页面对象有 3 种:
|
||||
|
||||
- `ChromiumPage`:单纯用于操作浏览器的页面对象
|
||||
|
||||
- `SessionPage`:单纯用于收发数据包的页面对象
|
||||
|
||||
- `WebPage`:整合浏览器控制和收发数据包于一体的页面对象
|
||||
|
||||
## 📍 `ChromiumPage`
|
||||
|
||||
`ChromiumPage`是用于操作浏览器的页面对象,它仅用于操作浏览器,而不能收发数据包。支持 Chroium 内核浏览器,如 Chrome、Edge 等。创建页面对象时,程序会自动启动浏览器,如果指定端口已存在浏览器,就接管该浏览器。
|
||||
@ -41,6 +51,8 @@ page.ele('#kw').input('DrissionPage')
|
||||
page.ele('@value=百度一下').click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `ChromiumElement`
|
||||
|
||||
`ChromiumElemnet`对象是浏览器页面元素对象,可对浏览器中的元素进行点击、文本输入、拖拽、运行 js 脚本等操作,也可以基于这个元素查找其下级或周围的元素。
|
||||
@ -62,6 +74,8 @@ links = ele.eles('tag:a')
|
||||
|
||||
除了最常用的`ChromiumElement`对象,浏览器还会产生`ChromiumFrame`、`ChromiumShadowRootElement`、`ChromiumTab`对象,详细用法见相关章节。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `SessionPage`
|
||||
|
||||
`SessionPage`是用于收发数据包的页面对象,它仅用于收发数据包,而不能操作浏览器。
|
||||
@ -79,12 +93,14 @@ ele = page('#kw')
|
||||
print(ele.html)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `SessionElement`
|
||||
|
||||
`SessionElement`对象是`SessionPage`产生的元素对象,可以读取元素信息,或基于它进行下级元素查找、相对定位其它元素,但不能执行点击等操作。
|
||||
@ -97,6 +113,8 @@ tag = ele.tag
|
||||
ele1 = ele.ele('@name=name1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `WebPage`
|
||||
|
||||
`WebPage`是整合了上面两者的页面对象,既可控制浏览器,又可收发数据包,并且可以在这两者之间共享登录信息。
|
||||
@ -126,7 +144,7 @@ for result in results:
|
||||
print(result.text)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
DrissionPage: 一个整合了selenium和requests_html的模块,...
|
||||
@ -143,6 +161,8 @@ DrissionPagev2.2.1 发布,WEB 自动化测试集成工具
|
||||
|
||||
详细使用方法见“创建页面对象”和“操作页面”章节。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 工作模式
|
||||
|
||||
如上所述,`WebPage`既可控制浏览器,也可用数据包方式访问网络数据。它有两种工作方式:d 模式和 s 模式。
|
||||
@ -154,12 +174,16 @@ d 模式既表示 Driver,还有 Dynamic 的意思。
|
||||
d 模式用于控制浏览器,不仅可以读取浏览器获取到的信息,还能对页面进行操作,如点击、填写、开关标签页、改变元素属性、执行 js 脚本等等。
|
||||
d 模式功能强大,但运行速度受浏览器制约非常缓慢,而且需要占用大量内存。
|
||||
|
||||
---
|
||||
|
||||
## 📍 s 模式
|
||||
|
||||
s 模式既表示 Session,还有 speed、silence 的意思。
|
||||
s 模式的运行速度比 d 模式快几个数量级,但只能基于数据包进行读取或发送,不能对页面进行操作,不能运行 js。
|
||||
爬取数据时,如网站数据包较为简单,应首选 s 模式。
|
||||
|
||||
---
|
||||
|
||||
## 📍 模式切换
|
||||
|
||||
`WebPage`对象可以在 d 模式和 s 模式之间切换,这通常用于以下情况:
|
||||
@ -184,12 +208,16 @@ ele = ele.s_ele()
|
||||
rows = ele.eles('tag:tr')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结构图
|
||||
|
||||
`WebPage`继承自`ChromiumPage`和`SessionPage`,前者负责控制浏览器,后者负责数据包收发,因此`WebPage`既能控制浏览器,也能收发数据包,并且能在两种模式中共享登录状态。
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# ✔️ 配置管理
|
||||
|
||||
无论 requests 还是浏览器,都通常须要一些配置信息才能正常工作,如长长的`user_agent`、浏览器 exe 文件路径、浏览器配置等。这些代码往往是繁琐而重复的,不利于代码的简洁。
|
||||
@ -199,6 +227,8 @@ rows = ele.eles('tag:tr')
|
||||
|
||||
?> **Tips:** <br>当须要打包程序时,必须把配置写到代码里,或打包后手动复制配置文件到运行路径,否则会报错。详见相关章节。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 定位符
|
||||
|
||||
定位符用于定位页面中的元素,是本库一大特色,能够用非常简明的方式来获取元素,简洁易用。可读性和易用性高于 xpath 等其它方式,并且兼容 xpath、css selector、selenium 定位符。
|
46
docs/4_SessionPge/0_introduction.md
Normal file
46
docs/4_SessionPge/0_introduction.md
Normal file
@ -0,0 +1,46 @@
|
||||
`SessionPage`对象和`WebPage`对象的 s 模式,可用收发数据包的形式访问网页。
|
||||
|
||||
本章介绍`SessionPage`。
|
||||
|
||||
顾名思义,`SessionPage`是一个使用使用`Session`(requests 库)对象的页面,它使用 POM 模式封装了网络连接和 html 解析功能,使收发数据包也可以像操作页面一样便利。
|
||||
|
||||
并且,由于加入了本库独创的查找元素方法,使数据的采集便利性远超 requests + beautifulsoup 等组合。
|
||||
|
||||
`SessionPage`是本库几种页面对象中最简单的,我们先从它开始入手。
|
||||
|
||||
我们看个简单的例子,来了解`SessionPage`的工作方式。
|
||||
|
||||
---
|
||||
|
||||
获取 gitee 推荐项目第一页所有项目。
|
||||
|
||||
```python
|
||||
# 导入
|
||||
from DrissionPage import SessionPage
|
||||
# 创建页面对象
|
||||
page = SessionPage()
|
||||
# 访问网页
|
||||
page.get('https://gitee.com/explore/all')
|
||||
# 在页面中查找元素
|
||||
items = page.eles('t:h3')
|
||||
# 遍历元素
|
||||
for item in items[:-1]:
|
||||
# 获取当前<h3>元素下的<a>元素
|
||||
lnk = item('tag:a')
|
||||
# 打印<a>元素文本和href属性
|
||||
print(lnk.text, lnk.link)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
七年觐汐/wx-calendar https://gitee.com/qq_connect-EC6BCC0B556624342/wx-calendar
|
||||
ThingsPanel/thingspanel-go https://gitee.com/ThingsPanel/thingspanel-go
|
||||
APITable/APITable https://gitee.com/apitable/APITable
|
||||
Indexea/ideaseg https://gitee.com/indexea/ideaseg
|
||||
CcSimple/vue-plugin-hiprint https://gitee.com/CcSimple/vue-plugin-hiprint
|
||||
william_lzw/ExDUIR.NET https://gitee.com/william_lzw/ExDUIR.NET
|
||||
anolis/ancert https://gitee.com/anolis/ancert
|
||||
cozodb/cozo https://gitee.com/cozodb/cozo
|
||||
后面省略...
|
||||
```
|
88
docs/4_SessionPge/1_create_page_object.md
Normal file
88
docs/4_SessionPge/1_create_page_object.md
Normal file
@ -0,0 +1,88 @@
|
||||
`SessionPage`对象和`WebPage`对象的 s 模式都能收发数据包,本节只介绍`SessionPage`的创建,在`WebPage`的章节再对其进行介绍。
|
||||
|
||||
# ✔️ `SessionPage`初始化参数
|
||||
|
||||
`SessionPage`对象是 3 种页面对象中最简单的。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:--------------------:|:-----------------------------:|:------:| --------------------------------------------------------------- |
|
||||
| `session_or_options` | `Session`<br>`SessionOptions` | `None` | 传入`Session`对象时使用该对象收发数据包;传入`SessionOptions`对象时用该配置创建`Session`对象 |
|
||||
| `timeout` | `float` | `None` | 连接超时时间,为`None`则从配置文件中读取 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 直接创建
|
||||
|
||||
这种方式代码最简洁,程序会从配置文件中读取配置,自动生成页面对象。
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
```
|
||||
|
||||
`SessionPage`无须控制浏览器,无须做任何配置即可使用。
|
||||
|
||||
!>**注意:**<br>这种方式的程序不能直接打包,因为使用到 ini 文件。可参考“打包程序”一节的方法。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 通过配置信息创建
|
||||
|
||||
如果须要在使用前进行一些配置,可使用`SessionOptions`。它是专门用于设置`Session`对象初始状态的类,内置了常用的配置。详细使用方法见“启动配置”一节。
|
||||
|
||||
## 📍 使用方法
|
||||
|
||||
在`SessionPage`创建时,将已创建和设置好的`SessionOptions`对象以参数形式传递进去即可。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| ----------- | ------ | ------ | ------------------------ |
|
||||
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
|
||||
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
|
||||
|
||||
!>**注意:**<br> `Session`对象创建后再修改这个配置是没有效果的。
|
||||
|
||||
```python
|
||||
# 导入 SessionOptions
|
||||
from DrissionPage import SessionPage, SessionOptions
|
||||
|
||||
proxies = {'http': 'http://127.0.0.1:1080',
|
||||
'https': 'http://127.0.0.1:1080'}
|
||||
|
||||
# 创建配置对象,并设置代理信息
|
||||
so = SessionOptions().set_proxies(proxies)
|
||||
# 用该配置创建页面对象
|
||||
page = SessionPage(session_or_options=so)
|
||||
```
|
||||
|
||||
?>**Tips:**<br>您可以把配置保存到配置文件以后自动读取,详见”启动配置“章节。
|
||||
|
||||
---
|
||||
|
||||
## 📍 从指定 ini 文件创建
|
||||
|
||||
以上方法是使用默认 ini 文件中保存的配置信息创建对象,你可以保存一个 ini 文件到别的地方,并在创建对象时指定使用它。
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage, SessionOptinos
|
||||
|
||||
# 创建配置对象时指定要读取的ini文件路径
|
||||
so = SessionOptinos(ini_path=r'./config1.ini')
|
||||
# 使用该配置对象创建页面
|
||||
page = SessionPage(session_or_options=so)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 传递控制权
|
||||
|
||||
当须要使用多个页面对象共同操作一个页面时,可在页面对象创建时接收另一个页面间对象传递过来的`Session`对象,以达到多个页面对象同时使用一个`Session`对象的效果。
|
||||
|
||||
```python
|
||||
# 创建一个页面
|
||||
page1 = SessionPage()
|
||||
# 获取页面对象内置的Session对象
|
||||
session = page1.session
|
||||
# 在第二个页面对象初始化时传递该对象
|
||||
page2 = SessionPage(session_or_options=session)
|
||||
```
|
126
docs/4_SessionPge/2_visit_web_page.md
Normal file
126
docs/4_SessionPge/2_visit_web_page.md
Normal file
@ -0,0 +1,126 @@
|
||||
`SessionPage`和`WebPage`的 s 模式基于 requests 进行网络连接,因此可使用 requests 内置的所有请求方式,包括`get()`、`post()`、`head()`、`options()`、`put()`
|
||||
、`patch()`、`delete()`。不过本库目前只对`get()`和`post()`做了封装和优化,其余方式可通过调用页面对象内置的`Session`对象使用。这里只对`SessionPage`
|
||||
进行说明,后面章节再单独介绍`WebPage`。
|
||||
|
||||
# ✔️ `get()`
|
||||
|
||||
`get()`方法语法与 requests 的`get()`方法一致,在此基础上增加了连接失败重试功能。与 requests 不一样的是,它不返回`Response`对象。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:----------------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 必填 | 目标 url |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `int`<br>`float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 加载超时时间(秒) |
|
||||
| `**kwargs` | - | `None` | 连接所需其它参数,具体见 requests 用法 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
`**kwargs`参数与 requests 中该参数使用方法一致,但有一个特点,如果该参数中设置了某一项(如`headers`),该项中的每个项会覆盖从配置中读取的同名项,而不会整个覆盖。
|
||||
就是说,如果想继续使用配置中的`headers`信息,而只想修改其中一项,只需要传入该项的值即可。这样可以简化代码逻辑。
|
||||
|
||||
实用功能:
|
||||
|
||||
- 程序会根据要访问的网址自动在`headers`中加入`Host`和`Referer`项
|
||||
- 程序会自动从返回内容中确定编码,一般情况无须手动设置
|
||||
|
||||
普通访问网页:
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
page.get('http://g1879.gitee.io/drissionpage')
|
||||
```
|
||||
|
||||
使用连接参数访问网页:
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
|
||||
url = 'https://www.baidu.com'
|
||||
headers = {'referer': 'gitee.com'}
|
||||
cookies = {'name': 'value'}
|
||||
proxies = {'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
|
||||
page.get(url, headers=headers, cookies=cookies, proxies=proxies)
|
||||
```
|
||||
|
||||
!>**注意:**<br>s 模式访问时默认设置`redirect`参数为`False`,即访问重定向链接时须手动处理。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `post()`
|
||||
|
||||
此方法是用 post 方式请求页面。用法与`get()`一致。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:---------------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 必填 | 目标url |
|
||||
| `data` | `dict`<br>`str` | `None` | 提交的数据 |
|
||||
| `json` | `dict`<br>`str` | `None` | 提交的数据 |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `float` | `None` | 加载超时时间(秒) |
|
||||
| `**kwargs` | - | `None` | 连接所需其它参数,具体见 requests 用法 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
data = {'username': 'xxxxx', 'pwd': 'xxxxx'}
|
||||
|
||||
page.post('http://example.com', data=data)
|
||||
# 或
|
||||
page.post('http://example.com', json=data)
|
||||
```
|
||||
|
||||
`data`参数和`json`参数都可接收`str`和`dict`格式数据,即有以下 4 种传递数据的方式:
|
||||
|
||||
```python
|
||||
# 向 data 参数传入字符串
|
||||
page.post(url, data='abc=123')
|
||||
|
||||
# 向 data 参数传入字典
|
||||
page.post(url, data={'abc': '123'})
|
||||
|
||||
# 向 json 参数传入字符串
|
||||
page.post(url, json='abc=123')
|
||||
|
||||
# 向 json 参数传入字典
|
||||
page.post(url, json={'abc': '123'})
|
||||
```
|
||||
|
||||
具体使用哪种,按服务器要求而定。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 其它请求方式
|
||||
|
||||
本库只针对常用的 get 和 post 方式作了优化,但也可以通过提取页面对象内的`Session`对象以原生 requests 代码方式执行其它请求方式。
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
# 获取内置的 Session 对象
|
||||
session = page.session
|
||||
# 以 head 方式发送请求
|
||||
response = session.head('https://www.baidu.com')
|
||||
print(response.headers)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
{'Accept-Ranges': 'bytes', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Length': '277', 'Content-Type': 'text/html', 'Date': 'Tue, 04 Jan 2022 06:49:18 GMT', 'Etag': '"575e1f72-115"', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:26 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18'}
|
||||
```
|
181
docs/4_SessionPge/3_get_page_info.md
Normal file
181
docs/4_SessionPge/3_get_page_info.md
Normal file
@ -0,0 +1,181 @@
|
||||
成功访问网页后,可使用`SessionPage`自身属性和方法获取页面信息。
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
page.get('http://www.baidu.com')
|
||||
# 获取页面标题
|
||||
print(page.title)
|
||||
# 获取页面html
|
||||
print(page.html)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
百度一下,你就知道
|
||||
<!DOCTYPE html>
|
||||
<!--STATUS OK--><html> <head><meta http-equi...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 页面信息
|
||||
|
||||
## 📍 `url`
|
||||
|
||||
此属性返回当前访问的 url。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `url_available`
|
||||
|
||||
此属性以布尔值返回当前链接是否可用。
|
||||
|
||||
**返回类型:**`bool`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `title`
|
||||
|
||||
此属性返回当前页面`title`文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回当前页面 html 文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `json`
|
||||
|
||||
此属性把返回内容解析成 json。
|
||||
比如请求接口时,若返回内容是 json 格式,用`html`属性获取的话会得到一个字符串,用此属性获取可将其解析成`dict`。
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 运行参数信息
|
||||
|
||||
## 📍 `timeout`
|
||||
|
||||
此属性返回网络请求超时时间。默认为 10,可对其赋值设置。
|
||||
|
||||
**返回类型:**`int`、`float`
|
||||
|
||||
```python
|
||||
# 创建页面对象时指定
|
||||
page = SessionPage(timeout=5)
|
||||
|
||||
# 修改 timeout
|
||||
page.timeout = 20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `retry_times`
|
||||
|
||||
此属性为网络连接失败时的重试次数。默认为 3,可对其赋值。
|
||||
|
||||
**返回类型:**`int`
|
||||
|
||||
```python
|
||||
# 修改重试次数
|
||||
page.retry_times = 5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `retry_interval`
|
||||
|
||||
此属性为网络连接失败时的重试等待间隔秒数。默认为 2,可对其赋值。
|
||||
|
||||
**返回类型:**`int`、`float`
|
||||
|
||||
```python
|
||||
# 修改重试等待间隔时间
|
||||
page.retry_interval = 1.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ cookies 信息
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
此属性以`dict`方式返回当前页面所使用的 cookies。
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get_cookies()`
|
||||
|
||||
此方法获取 cookies 并以 cookie 组成的`list`形式返回。
|
||||
|
||||
**返回类型:**`dict`、`list`
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:------:|:-------:| --------------------------------------- |
|
||||
| `as_dict` | `bool` | `False` | 是否以字典方式返回结果,为`False`返回 cookie 组成的`list` |
|
||||
| `all_domains` | `bool` | `False` | 是否返回所有域的 cookies,为`False`则指返回当前域名的 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------- |
|
||||
| `dict` | cookies 字典 |
|
||||
| `list` | cookies 组成的列表 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
page.get('http://www.baidu.com')
|
||||
page.get('http://gitee.com')
|
||||
|
||||
for i in page.get_cookies(as_dict=False, all_domains=True):
|
||||
print(i)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'domain': '.baidu.com', 'domain_specified': True, ......}
|
||||
......
|
||||
{'domain': 'gitee.com', 'domain_specified': False, ......}
|
||||
......
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 内嵌对象
|
||||
|
||||
## 📍 `session`
|
||||
|
||||
此属性返回当前页面对象使用的`Session`对象。
|
||||
|
||||
**返回类型:**`Session`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `response`
|
||||
|
||||
此属性为请求网页后生成的`Response`对象,本库没实现的功能可直接获取此属性调用 requests 库的原生功能。
|
||||
|
||||
**返回类型:**`Response`
|
||||
|
||||
```python
|
||||
# 打印连接状态
|
||||
r = page.response
|
||||
print(r.status_code)
|
||||
```
|
718
docs/4_SessionPge/4_find_elements.md
Normal file
718
docs/4_SessionPge/4_find_elements.md
Normal file
@ -0,0 +1,718 @@
|
||||
本节介绍如何获取元素对象。
|
||||
|
||||
定位元素是自动化最重要的的技能,虽然可在开发者工具直接复制绝对路径,但这样做一来代码冗长,可读性低,二来难以应付动态变化的页面。
|
||||
因此本库提供一套简洁易用的语法,用于快速定位元素,并且内置等待功能、支持链式查找,减少了代码的复杂性。
|
||||
|
||||
定位元素大致分为三种方法:
|
||||
|
||||
- 在页面或元素内查找子元素
|
||||
- 根据 DOM 结构相对定位
|
||||
- 根据页面布局位置相对定位
|
||||
|
||||
# ✔️ 示例
|
||||
|
||||
先看一些示例,后面在详细讲解用法。
|
||||
|
||||
## 📍 简单示例
|
||||
|
||||
假设有这样一个页面,本节示例皆使用此页面:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<div id="one">
|
||||
<p class="p_cls" name="row1">第一行</p>
|
||||
<p class="p_cls" name="row2">第二行</p>
|
||||
<p class="p_cls">第三行</p>
|
||||
</div>
|
||||
<div id="two">
|
||||
第二个div
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
我们可以用页面对象去获取其中的元素:
|
||||
|
||||
```python
|
||||
# 获取 id 为 one 的元素
|
||||
div1 = page.ele('#one')
|
||||
|
||||
# 获取 name 属性为 row1 的元素
|
||||
p1 = page.ele('@name=row1')
|
||||
|
||||
# 获取包含“第二个div”文本的元素
|
||||
div2 = page.ele('第二个div')
|
||||
|
||||
# 获取所有div元素
|
||||
div_list = page.eles('tag:div')
|
||||
```
|
||||
|
||||
也可以获取到一个元素,然后在它里面或周围查找元素:
|
||||
|
||||
```python
|
||||
# 获取到一个元素div1
|
||||
div1 = page.ele('#one')
|
||||
|
||||
# 在div1内查找所有p元素
|
||||
p_list = div1.eles('tag:p')
|
||||
|
||||
# 获取div1后面一个元素
|
||||
div2 = div1.next()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 实际示例
|
||||
|
||||
复制此代码可直接运行查看结果。
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取包含“全部推荐项目”文本的 ul 元素
|
||||
ul_ele = page.ele('tag:ul@@text():全部推荐项目')
|
||||
|
||||
# 获取该 ul 元素下所有 a 元素
|
||||
titles = ul_ele.eles('tag:a')
|
||||
|
||||
# 遍历列表,打印每个 a 元素的文本
|
||||
for i in titles:
|
||||
print(i.text)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
全部推荐项目
|
||||
前沿技术
|
||||
智能硬件
|
||||
IOT/物联网/边缘计算
|
||||
车载应用
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 查找元素方法
|
||||
|
||||
## 📍 查找单个元素
|
||||
|
||||
🔸 `ele()`
|
||||
|
||||
页面对象和元素对象都拥有此方法,用于查找第一个匹配条件的元素。
|
||||
|
||||
页面对象和元素对象的`ele()`方法参数名称稍有不同,但用法一样。
|
||||
|
||||
?>**Tips:**<br>使用 xpath 可直接获取后代元素的属性。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------------:|:----------------------------------------------:|:------:| -------------------------------------------- |
|
||||
| `loc_or_str`(元素对象) | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
| `loc_or_ele`(页面对象) | `str`<br>`SessionElement`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串、loc 元组或一个`SessionElement`对象 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 不起实际作用,用于和`ChromiumElement`对应,便于无差别调用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------------- |
|
||||
| `SessionElement` | 返回查找到的第一个符合条件的元素对象 |
|
||||
| `None` | 未找到符合条件的元素时返回`None` |
|
||||
| `str` | 使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage()
|
||||
|
||||
# 在页面内查找元素
|
||||
ele1 = page.ele('#one')
|
||||
|
||||
# 在元素内查找后代元素
|
||||
ele2 = ele1.ele('第二行')
|
||||
|
||||
# 使用 xpath 获取后代中第一个 div 元素的 class 属性(元素内查找可用)
|
||||
ele_class = ele1.ele('xpath://p/@class')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 查找多个元素
|
||||
|
||||
🔸 `eles()`
|
||||
|
||||
此方法与`ele()`相似,但返回的是匹配到的所有元素组成的列表,用 xpath 获取元素属性时,返回属性文本组成的列表。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ------------------------------------- |
|
||||
| `loc_or_str` | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 不起实际作用,用于和`ChromiumElement`对应,便于无差别调用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| ---------------------------- |
|
||||
| `List[SessionElement]` | 返回找到的所有`SessionElement`组成的列表 |
|
||||
| `List[str]` | 使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取ele元素内的所有p元素
|
||||
p_eles = ele.eles('tag:p')
|
||||
# 打印第一个p元素的文本
|
||||
print(p_eles[0])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 查找语法
|
||||
|
||||
我们使用一套简洁高效的语法去定位元素,大大简化了定位元素的代码量,增强了功能,也兼容 css selector、xpath、selenium 原生的 loc 元组。
|
||||
|
||||
🔸 **匹配模式** 指字符串是否完全匹配,有以下两种:
|
||||
|
||||
## 📍 精确匹配符 `=`
|
||||
|
||||
表示精确匹配,匹配完全符合的文本或属性。
|
||||
|
||||
---
|
||||
|
||||
## 📍 模糊匹配符 `:`
|
||||
|
||||
表示模糊匹配,匹配含有某个字符串的文本或属性。
|
||||
|
||||
---
|
||||
|
||||
🔸 **关键字** 是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
|
||||
|
||||
## 📍 id 匹配符 `#`
|
||||
|
||||
表示`id`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
|
||||
|
||||
```python
|
||||
# 在页面中查找id属性为one的元素
|
||||
ele1 = page.ele('#one')
|
||||
|
||||
# 在ele1元素内查找id属性包含ne文本的元素
|
||||
ele2 = ele1.ele('#:ne')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 class 匹配符 `.`
|
||||
|
||||
表示`class`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
|
||||
|
||||
```python
|
||||
# 查找class属性为p_cls的元素
|
||||
ele2 = ele1.ele('.p_cls')
|
||||
|
||||
# 查找class属性包含_cls文本的元素
|
||||
ele2 = ele1.ele('.:_cls')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 单属性匹配符 `@`
|
||||
|
||||
表示某个属性,只匹配一个属性。
|
||||
`@`关键字只有一个简单功能,就是匹配`@`后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在`@`或`@@`,也作为要匹配的内容对待。
|
||||
|
||||
!> **注意:**
|
||||
如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
|
||||
|
||||
```python
|
||||
# 查找name属性为row1的元素
|
||||
ele2 = ele1.ele('@name=row1')
|
||||
|
||||
# 查找name属性包含row文本的元素
|
||||
ele2 = ele1.ele('@name:row')
|
||||
|
||||
# 查找有name属性的元素
|
||||
ele2 = ele1.ele('@name')
|
||||
|
||||
# 查找没有任何属性的元素
|
||||
ele2 = ele1.ele('@')
|
||||
|
||||
# 查找email属性为abc@def.com的元素,有多个@也不会重复处理
|
||||
ele2 = ele1.ele('@email=abc@def.com')
|
||||
|
||||
# 属性中有特殊字符的情形,匹配abc@def属性等于v的元素
|
||||
ele2 = ele1.ele('css:div[abc\@def="v"]')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 多属性匹配符 `@@`
|
||||
|
||||
多属性匹配时使用,个数不限。还能匹配要忽略的元素,匹配文本时也和`@`不一样。
|
||||
`@@`后跟 - 时,表示 not。如:
|
||||
|
||||
- `@@-name`表示匹配没有`name`属性的元素
|
||||
|
||||
- `@@-name=ele_name`表示匹配`name`属性不为`ele_name`的元素
|
||||
|
||||
如有以下情况,不能使用此方式,须改用 xpath 的方式:
|
||||
|
||||
- 匹配文本或属性中出现`@@`
|
||||
|
||||
- 属性名本身以`-`开头
|
||||
|
||||
!> **注意:**:<br>如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
|
||||
|
||||
```python
|
||||
# 查找name属性为name且class属性包含cls文本的元素
|
||||
ele2 = ele1.ele('@@name=row1@@class:cls')
|
||||
|
||||
# 查找没有class属性的元素
|
||||
ele2 = ele1.ele('@@-class')
|
||||
|
||||
# 查找name属性不包含row1的元素
|
||||
ele2 = ele1.ele('@@-name:row1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 文本匹配符 `text`
|
||||
|
||||
要匹配的文本,查询字符串如开头没有任何关键字,也表示根据传入的文本作模糊查找。
|
||||
如果元素内有多个直接的文本节点,精确查找时可匹配所有文本节点拼成的字符串,模糊查找时可匹配每个文本节点。
|
||||
|
||||
没有任何匹配符时,默认匹配文本。
|
||||
|
||||
```python
|
||||
# 查找文本为“第二行”的元素
|
||||
ele2 = ele1.ele('text=第二行')
|
||||
|
||||
# 查找文本包含“第二”的元素
|
||||
ele2 = ele1.ele('text:第二')
|
||||
|
||||
# 与上一行一致
|
||||
ele2 = ele1.ele('第二')
|
||||
```
|
||||
|
||||
?> **Tips:** <br>若要查找的文本包含`text:` ,可下面这样写,即第一个`text:` 为关键字,第二个是要查找的内容:
|
||||
|
||||
```python
|
||||
ele2 = page.ele('text:text:')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 文本匹配符 `text()`
|
||||
|
||||
作为查找属性时使用的文本关键字,必须与`@`或`@@`配合使用。
|
||||
|
||||
```python
|
||||
# 查找文本为“第二行”的元素
|
||||
ele2 = ele1.ele('@text()=第二行')
|
||||
|
||||
# 查找文本包含“第二行”的元素
|
||||
ele2 = ele1.ele('@text():二行')
|
||||
|
||||
# 查找文本为“第二行”且class属性为p_cls的元素
|
||||
ele2 = ele1.ele('@@text()=第二行@@class=p_cls')
|
||||
|
||||
# 查找文本为 some text 且没有任何属性的元素(因第一个 @@ 后为空)
|
||||
ele2 = ele1.ele('@@@@text():some text')
|
||||
|
||||
# 查找直接子文本包含 some text 字符串的元素
|
||||
ele = page.ele('@text():二行')
|
||||
|
||||
# 查找元素内部包含 some text 字符串的元素
|
||||
ele = page.ele('@@text():二行')
|
||||
```
|
||||
|
||||
须要注意的是,`'text=xxxx'`与`'@text()=xxxx'`使用上是有细微差别的。
|
||||
|
||||
`text=`表示在元素的直接子文本节点中匹配,`@text()=`会忽略一些文本标签,在整个元素的内容里匹配。
|
||||
|
||||
---
|
||||
|
||||
## 📍 类型匹配符 `tag`
|
||||
|
||||
表示元素的标签,只在语句最前面且单独使用时生效,可与`@`或`@@`配合使用。`tag:`与`tag=`效果一致。
|
||||
|
||||
```python
|
||||
# 定位div元素
|
||||
ele2 = ele1.ele('tag:div')
|
||||
|
||||
# 定位class属性为p_cls的p元素
|
||||
ele2 = ele1.ele('tag:p@class=p_cls')
|
||||
|
||||
# 定位文本为"第二行"的p元素
|
||||
ele2 = ele1.ele('tag:p@text()=第二行')
|
||||
|
||||
# 定位class属性为p_cls且文本为“第二行”的p元素
|
||||
ele2 = ele1.ele('tag:p@@class=p_cls@@text()=第二行')
|
||||
|
||||
# 查找直接文本节点包含“二行”字符串的p元素
|
||||
ele2 = ele1.ele('tag:p@text():二行')
|
||||
|
||||
# 查找内部文本节点包含“二行”字符串的p元素
|
||||
ele2 = ele1.ele('tag:p@@text():二行')
|
||||
```
|
||||
|
||||
!> **注意:** <br>`tag:div@text():text` 和 `tag:div@@text():text` 是有区别的,前者只在`div`的直接文本节点搜索,后者搜索`div`的整个内部。
|
||||
|
||||
---
|
||||
|
||||
## 📍 css selector 匹配符 `css`
|
||||
|
||||
表示用 css selector 方式查找元素。`css:`与`css=`效果一致。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('css:.div')
|
||||
|
||||
# 查找 div 子元素元素,这个写法是本库特有,原生不支持
|
||||
ele2 = ele1.ele('css:>div')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 xpath 匹配符 `xpath`
|
||||
|
||||
表示用 xpath 方式查找元素。`xpath:`与`xpath=`效果一致。
|
||||
在元素中查找时,该方法支持完整的 xpath 语法,能使用 xpath 直接获取元素属性,selenium 不支持这种用法。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('xpath:.//div')
|
||||
|
||||
# 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
|
||||
ele2 = ele1.ele('xpath://div')
|
||||
|
||||
# 获取 div 元素的 class 属性,返回字符串
|
||||
txt = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
?> **Tips:** <br>查找元素的后代时,selenium 原生代码要求 xpath 前面必须加`.`,否则会变成在全个页面中查找。作者觉得这个设计是画蛇添足,既然已经通过元素查找了,自然应该只查找这个元素内部的元素。所以,用
|
||||
xpath 在元素下查找时,最前面`//`或`/`前面的`.`可以省略。
|
||||
|
||||
---
|
||||
|
||||
## 📍 selenium 的 loc 元组
|
||||
|
||||
查找方法能直接接收 selenium 原生定位元组进行查找。
|
||||
|
||||
```python
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
# 查找id为one的元素
|
||||
loc1 = (By.ID, 'one')
|
||||
ele = page.ele(loc1)
|
||||
|
||||
# 按 xpath 查找
|
||||
loc2 = (By.XPATH, '//p[@class="p_cls"]')
|
||||
ele = page.ele(loc2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 相对定位
|
||||
|
||||
以下方法可以以某元素为基准,在 DOM 中按照条件获取其兄弟元素、祖先元素、文档前后元素。
|
||||
除获取元素外,还能通过 xpath 获取任意节点内容,如文本节点、注释节点。这在处理元素和文本节点混排的时候非常有用。
|
||||
|
||||
!>**注意:**<br>如果元素在`<iframe>`中,相对定位不能超越`<iframe>`文档。
|
||||
|
||||
## 📍 获取父级元素
|
||||
|
||||
🔸 `parent()`
|
||||
|
||||
此方法获取当前元素某一级父元素,可指定筛选条件或层数。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------------:|:-----------------------------------:|:---:| --------------------- |
|
||||
| `level_or_loc` | `int`<br>`str`<br>`Tuple[str, str]` | `1` | 第几级父元素,或定位符用于在祖先元素中查找 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------- |
|
||||
| `SessionElement` | 获取到的元素对象 |
|
||||
| `None` | 未获取到结果时返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 的第二层父元素
|
||||
ele2 = ele1.parent(2)
|
||||
|
||||
# 获取 ele1 父元素中 id 为 id1 的元素
|
||||
ele2 = ele1.parent('#id1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取后面的兄弟元素
|
||||
|
||||
🔸 `next()`
|
||||
|
||||
此方法返回当前元素后面的某一个同级元素,可指定筛选条件和第几个。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `index` | `int` | `1` | 查询结果中的第几个 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------- |
|
||||
| `SessionElement` | 获取到的元素对象 |
|
||||
| `None` | 未获取到结果时返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第一个兄弟元素
|
||||
ele2 = ele1.next()
|
||||
|
||||
# 获取 ele1 后面第 3 个兄弟元素
|
||||
ele2 = ele1.next(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.next('tag:div', 3)
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.next('xpath:text()', 1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🔸 `nexts()`
|
||||
|
||||
此方法返回当前元素后面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| -------- |
|
||||
| `List[SessionElement]` | 获取到的元素对象 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面所有兄弟元素
|
||||
eles = ele1.nexts()
|
||||
|
||||
# 获取 ele1 后面所有 div 兄弟元素
|
||||
divs = ele1.nexts('tag:div')
|
||||
|
||||
# 获取 ele1 后面的所有文本节点
|
||||
txts = ele1.nexts('xpath:text()')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取前面的兄弟元素
|
||||
|
||||
🔸 `prev()`
|
||||
|
||||
此方法返回当前元素前面的某一个同级元素,可指定筛选条件和第几个。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `index` | `int` | `1` | 查询结果中的第几个 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------- |
|
||||
| `SessionElement` | 获取到的元素对象 |
|
||||
| `None` | 未获取到结果时返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第一个兄弟元素
|
||||
ele2 = ele1.prev()
|
||||
|
||||
# 获取 ele1 前面第 3 个兄弟元素
|
||||
ele2 = ele1.prev(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.prev(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.prev(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🔸 `prevs()`
|
||||
|
||||
此方法返回当前元素前面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| -------- |
|
||||
| `List[SessionElement]` | 获取到的元素对象 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有兄弟元素
|
||||
eles = ele1.prevs()
|
||||
|
||||
# 获取 ele1 前面所有 div 兄弟元素
|
||||
divs = ele1.prevs('tag:div')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 在后面文档中查找元素
|
||||
|
||||
🔸 `after()`
|
||||
|
||||
此方法返回当前元素后面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `index` | `int` | `1` | 查询结果中的第几个 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------- |
|
||||
| `SessionElement` | 获取到的元素对象 |
|
||||
| `None` | 未获取到结果时返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第 3 个元素
|
||||
ele2 = ele1.after(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 元素
|
||||
ele2 = ele1.after('tag:div', 3)
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.after('xpath:text()', 1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🔸 `afters()`
|
||||
|
||||
此方法返回当前元素后面符合条件的全部元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| -------- |
|
||||
| `List[SessionElement]` | 获取到的元素对象 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 后所有元素
|
||||
eles = ele1.afters()
|
||||
|
||||
# 获取 ele1 前面所有 div 元素
|
||||
divs = ele1.afters('tag:div')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 在前面文档中查找元素
|
||||
|
||||
🔸 `before()`
|
||||
|
||||
此方法返回当前元素前面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `index` | `int` | `1` | 查询结果中的第几个 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------- |
|
||||
| `SessionElement` | 获取到的元素对象 |
|
||||
| `None` | 未获取到结果时返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第 3 个元素
|
||||
ele2 = ele1.before(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 元素
|
||||
ele2 = ele1.before('tag:div', 3)
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.before('xpath:text()', 1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🔸 `befores()`
|
||||
|
||||
此方法返回当前元素前面全部符合条件的元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------- |
|
||||
| `filter_loc` | `str`<br>`Tuple[str, str]` | `''` | 用于筛选元素的查询语法 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 无实际作用 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| -------- |
|
||||
| `List[SessionElement]` | 获取到的元素对象 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有元素
|
||||
eles = ele1.befores()
|
||||
|
||||
# 获取 ele1 前面所有 div 元素
|
||||
divs = ele1.befores('tag:div')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 简化写法
|
||||
|
||||
为进一步精简代码,对语法进行了精简
|
||||
|
||||
- 定位语法都有其简化形式。
|
||||
- 页面和元素对象都实现了`__call__()`方法,可直接调用。
|
||||
- 所有查找方法都支持链式操作
|
||||
|
||||
示例:
|
||||
|
||||
```python
|
||||
# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
eles = page('#table_id').eles('t:tr')
|
||||
|
||||
# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
ele2 = ele1('.cls1')('tx=text')
|
||||
|
||||
# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
ele2 = ele1.sr('.cls')
|
||||
|
||||
# 按xpath 查找元素
|
||||
ele2 = ele1('x://div[@class="ele_class"]')
|
||||
```
|
||||
|
||||
简化写法对应列表
|
||||
|
||||
| 原写法 | 简化写法 |
|
||||
|:--------:|:------:|
|
||||
| `text` | `tx` |
|
||||
| `text()` | `tx()` |
|
||||
| `tag` | `t` |
|
||||
| `xpath` | `x` |
|
||||
| `css` | `c` |
|
306
docs/4_SessionPge/5_get_element_info.md
Normal file
306
docs/4_SessionPge/5_get_element_info.md
Normal file
@ -0,0 +1,306 @@
|
||||
`SessionPage`对象和`WebPage` 对象s 模式获取的元素是`SessionElement`,本节介绍其属性。
|
||||
|
||||
假设`ele`为以下`div`元素的对象,本节示例均使用该元素:
|
||||
|
||||
```html
|
||||
<div id="div1" class="divs">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
```
|
||||
|
||||
# ✔️ `html`
|
||||
|
||||
此属性返回元素的`outerHTML`文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.html)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
<div id="div1" class="divs">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `inner_html`
|
||||
|
||||
此属性返回元素的`innerHTML`文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.inner_html)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `tag`
|
||||
|
||||
此属性返回元素的标签名。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.tag)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
div
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `text`
|
||||
|
||||
此属性返回元素内所有文本组合成的字符串。
|
||||
该字符串已格式化,即已转码,已去除多余换行符,符合人读取习惯,便于直接使用。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.text)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
Hello World!
|
||||
行元素
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `raw_text`
|
||||
|
||||
此属性返回元素内原始文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.raw_text)
|
||||
```
|
||||
|
||||
输出(注意保留了元素间的空格和换行):
|
||||
|
||||
```console
|
||||
Hello World!
|
||||
行元素
|
||||
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `texts()`
|
||||
|
||||
此方法返回元素内所有**直接**子节点的文本,包括元素和文本节点。 它有一个参数`text_node_only`,为`True`时则只获取只返回不被包裹的文本节点。这个方法适用于获取文本节点和元素节点混排的情况。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------------:|:------:|:-------:| --------- |
|
||||
| `text_node_only` | `bool` | `False` | 是否只返回文本节点 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----------:| ---- |
|
||||
| `List[str]` | 文本列表 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
print(e.tests())
|
||||
print(e.texts(text_node_only=True))
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
['Hello World!', '行元素']
|
||||
['Hello World!']
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `comments`
|
||||
|
||||
此属性以列表形式返回元素内的注释。
|
||||
|
||||
**返回类型:**`List[str]`
|
||||
|
||||
```python
|
||||
print(ele.comments)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
[<!--这是注释-->]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `attrs`
|
||||
|
||||
此属性以字典形式返回元素所有属性及值。
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
```python
|
||||
print(ele.attrs)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
{'id': 'div1', 'class': 'divs'}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `attr()`
|
||||
|
||||
此方法返回元素某个`attribute`属性值。它接收一个字符串参数`attr`,返回该属性值文本,无该属性时返回`None`。
|
||||
此属性返回的`src`、`href`属性为已补充完整的路径。`text`属性为已格式化文本。
|
||||
|
||||
**返回类型:**`str`、`None`
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| ---- |
|
||||
| `attr` | `str` | 必填 | 属性名称 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------- |
|
||||
| `str` | 属性值文本 |
|
||||
| `None` | 没有该属性返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
print(ele.attr('id'))
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
div1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `link`
|
||||
|
||||
此方法返回元素的 href 属性或 src 属性,没有这两个属性则返回`None`。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```html
|
||||
<a href='http://www.baidu.com'>百度</a>
|
||||
```
|
||||
|
||||
假设`a_ele`为以上元素的对象:
|
||||
|
||||
```python
|
||||
print(a_ele.link)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
http://www.baidu.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `page`
|
||||
|
||||
此属性返回元素所在的页面对象。由 html 文本直接生成的`SessionElement`的`page`属性为`None`。
|
||||
|
||||
**返回类型:**`SessionPage`、`WebPage`
|
||||
|
||||
```python
|
||||
page = ele.page
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `xpath`
|
||||
|
||||
此属性返回当前元素在页面中 xpath 的绝对路径。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.xpath)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
/html/body/div
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `css_path`
|
||||
|
||||
此属性返回当前元素在页面中 css selector 的绝对路径。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(ele.css_path)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
:nth-child(1)>:nth-child(1)>:nth-child(1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 实际示例
|
||||
|
||||
以下示例可直接运行查看结果:
|
||||
|
||||
```python
|
||||
from DrissionPage import SessionPage
|
||||
|
||||
page = SessionPage('s')
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取推荐目录下所有 a 元素
|
||||
li_eles = page('tag:ul@@text():全部推荐项目').eles('t:a')
|
||||
|
||||
# 遍历列表
|
||||
for i in li_eles:
|
||||
# 获取并打印标签名、文本、href 属性
|
||||
print(i.tag, i.text, i.attr('href'))
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
a 全部推荐项目 https://gitee.com/explore/all
|
||||
a 前沿技术 https://gitee.com/explore/new-tech
|
||||
a 智能硬件 https://gitee.com/explore/hardware
|
||||
a IOT/物联网/边缘计算 https://gitee.com/explore/iot
|
||||
a 车载应用 https://gitee.com/explore/vehicle
|
||||
以下省略……
|
||||
```
|
@ -1,5 +1,6 @@
|
||||
`SessionOptions`对象用于管理`Session`对象连接配置。
|
||||
其使用逻辑与`ChromiumOptions`相似。
|
||||
本节介绍`SessionPage`的启动配置。
|
||||
|
||||
我们用`SessionOptions`对象管理`Session`对象初始配置。
|
||||
|
||||
!> **注意:** <br>`SessionOptions`仅用于管理启动配置,程序启动后再修改无效。
|
||||
|
||||
@ -11,9 +12,11 @@
|
||||
from DrissionPage import SessionOptions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `SessionOptions`
|
||||
|
||||
`SessionOptions`对象用于管理 Session 对象的初始化配置。可从配置文件中读取配置来进行初始化。
|
||||
`SessionOptions`对象用于管理`Session`对象的初始化配置。可从配置文件中读取配置来进行初始化。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:-----------:|:---------------:|:------:| ---------------------------------- |
|
||||
@ -30,7 +33,7 @@ so = SessionOptions()
|
||||
|
||||
默认情况下,`SessionOptions`对象会从 ini 文件中读取配置信息,当指定`read_file`参数为`False`时,则以默认配置创建。
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 使用方法
|
||||
|
||||
@ -51,9 +54,9 @@ so.set_cookies(cookies)
|
||||
page = SessionPage(session_or_options=so)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 设置方法
|
||||
# ✔️ 用于设置的方法
|
||||
|
||||
## 📍 `set_headers()`
|
||||
|
||||
@ -61,7 +64,7 @@ page = SessionPage(session_or_options=so)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:------:|:---:| -------------- |
|
||||
| `headers | `dict` | 无 | 完整的 headers 字典 |
|
||||
| `headers | `dict` | 必填 | 完整的 headers 字典 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
@ -73,7 +76,7 @@ page = SessionPage(session_or_options=so)
|
||||
so.set_headers = {'user-agent': 'Mozilla/5.0 (Macint...', 'connection': 'keep-alive' ...}
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_a_header()`
|
||||
|
||||
@ -81,8 +84,8 @@ so.set_headers = {'user-agent': 'Mozilla/5.0 (Macint...', 'connection': 'keep-al
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| ---- |
|
||||
| `attr` | `str` | 无 | 设置名称 |
|
||||
| `value` | `str` | 无 | 设置值 |
|
||||
| `attr` | `str` | 必填 | 设置名称 |
|
||||
| `value` | `str` | 必填 | 设置值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
@ -95,21 +98,21 @@ so.set_a_header('accept', 'text/html')
|
||||
so.set_a_header('Accept-Charset', 'GB2312')
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'accept': 'text/html', 'accept-charset': 'GB2312'}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `remove_a_header()`
|
||||
|
||||
此方法用于从`headers`中移除一个设置项。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| ------ |
|
||||
| `attr` | `str` | 无 | 要删除的设置 |
|
||||
| `attr` | `str` | 必填 | 要删除的设置 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
@ -121,7 +124,7 @@ so.set_a_header('Accept-Charset', 'GB2312')
|
||||
so.remove_a_header('accept')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_cookies()`
|
||||
|
||||
@ -129,7 +132,7 @@ so.remove_a_header('accept')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:-----------------------------------------------------------:|:---:| ------- |
|
||||
| `cookies` | `RequestsCookieJar`<br>`list`<br>`tuple`<br>`str`<br>`dict` | 无 | cookies |
|
||||
| `cookies` | `RequestsCookieJar`<br>`list`<br>`tuple`<br>`str`<br>`dict` | 必填 | cookies |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
@ -142,7 +145,7 @@ cookies = ['key1=val1; domain=xxxx', 'key2=val2; domain=xxxx']
|
||||
so.set_cookies(cookies)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_timeout()`
|
||||
|
||||
@ -150,13 +153,13 @@ so.set_cookies(cookies)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:----------------:|:---:| ------ |
|
||||
| `second` | `int`<br>`float` | 无 | 连接等待秒数 |
|
||||
| `second` | `int`<br>`float` | 必填 | 连接等待秒数 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_proxies()`
|
||||
|
||||
@ -164,7 +167,7 @@ so.set_cookies(cookies)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:------:| ------------------------------- |
|
||||
| `http` | `str` | 无 | http 代理地址 |
|
||||
| `http` | `str` | 必填 | http 代理地址 |
|
||||
| `https` | `str` | `None` | https 代理地址,为`None`时使用`http`参数的值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
@ -177,7 +180,7 @@ so.set_cookies(cookies)
|
||||
so.set_proxies('http://127.0.0.1:1080')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_paths()`
|
||||
|
||||
@ -185,13 +188,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------------:|:---------------:|:---:| -------- |
|
||||
| `download_path` | `str`<br>`Path` | 无 | 默认下载保存路径 |
|
||||
| `download_path` | `str`<br>`Path` | 必填 | 默认下载保存路径 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_auth()`
|
||||
|
||||
@ -199,13 +202,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:--------------------------:|:---:| ------- |
|
||||
| `auth` | `tuple`<br>`HTTPBasicAuth` | 无 | 认证元组或对象 |
|
||||
| `auth` | `tuple`<br>`HTTPBasicAuth` | 必填 | 认证元组或对象 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_hooks()`
|
||||
|
||||
@ -213,13 +216,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:------:|:---:| ---- |
|
||||
| `hooks` | `dict` | 无 | 回调方法 |
|
||||
| `hooks` | `dict` | 必填 | 回调方法 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_params()`
|
||||
|
||||
@ -227,13 +230,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:------:|:---:| ------ |
|
||||
| `params` | `dict` | 无 | 查询参数字典 |
|
||||
| `params` | `dict` | 必填 | 查询参数字典 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_cert()`
|
||||
|
||||
@ -241,13 +244,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:----------------:|:---:| ------- |
|
||||
| `cert` | `str`<br>`tuple` | 无 | 证书路径或元组 |
|
||||
| `cert` | `str`<br>`tuple` | 必填 | 证书路径或元组 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_verify()`
|
||||
|
||||
@ -255,13 +258,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:------:|:---:| ----------- |
|
||||
| `on_off` | `bool` | 无 | `bool`表示开或关 |
|
||||
| `on_off` | `bool` | 必填 | `bool`表示开或关 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `add_adapter()`
|
||||
|
||||
@ -269,14 +272,14 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:-------------:|:---:| --------- |
|
||||
| `url` | `str` | 无 | 适配器对应 url |
|
||||
| `adapter` | `HTTPAdapter` | 无 | 适配器对象 |
|
||||
| `url` | `str` | 必填 | 适配器对应 url |
|
||||
| `adapter` | `HTTPAdapter` | 必填 | 适配器对象 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_stream()`
|
||||
|
||||
@ -284,13 +287,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:------:|:---:| ----------- |
|
||||
| `on_off` | `bool` | 无 | `bool`表示开或关 |
|
||||
| `on_off` | `bool` | 必填 | `bool`表示开或关 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_trust_env()`
|
||||
|
||||
@ -298,13 +301,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:------:|:---:| ----------- |
|
||||
| `on_off` | `bool` | 无 | `bool`表示开或关 |
|
||||
| `on_off` | `bool` | 必填 | `bool`表示开或关 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_max_redirects()`
|
||||
|
||||
@ -312,13 +315,13 @@ so.set_proxies('http://127.0.0.1:1080')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| ------- |
|
||||
| `times` | `int` | 无 | 最大重定向次数 |
|
||||
| `times` | `int` | 必填 | 最大重定向次数 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ---------------- | ------ |
|
||||
| `SessionOptions` | 配置对象本身 |
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 保存设置到文件
|
||||
|
||||
@ -348,7 +351,7 @@ so.save()
|
||||
so.save(path=r'D:\tmp\settings.ini')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `save_to_default()`
|
||||
|
||||
@ -366,7 +369,7 @@ so.save(path=r'D:\tmp\settings.ini')
|
||||
so.save_to_default()
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ `SessionOptions`属性
|
||||
|
||||
@ -376,7 +379,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
@ -384,7 +387,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`list`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `proxies`
|
||||
|
||||
@ -393,7 +396,7 @@ so.save_to_default()
|
||||
**类型:**`dict`
|
||||
**格式:**{'http': 'http://xx.xx.xx.xx:xxxx', 'https': 'http://xx.xx.xx.xx:xxxx'}
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `auth`
|
||||
|
||||
@ -401,7 +404,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`tuple`、`HTTPBasicAuth`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `hooks`
|
||||
|
||||
@ -409,7 +412,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `params`
|
||||
|
||||
@ -417,7 +420,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `verify`
|
||||
|
||||
@ -425,7 +428,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `cert`
|
||||
|
||||
@ -433,7 +436,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`str`、`tuple`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `adapters`
|
||||
|
||||
@ -441,7 +444,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`List[HTTPAdapter]`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `stream`
|
||||
|
||||
@ -449,7 +452,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `trust_env`
|
||||
|
||||
@ -457,7 +460,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `max_redirects`
|
||||
|
||||
@ -465,7 +468,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`int`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `timeout`
|
||||
|
||||
@ -473,7 +476,7 @@ so.save_to_default()
|
||||
|
||||
**类型:**`int`、`float`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `download_path`
|
||||
|
44
docs/5_ChromiumPage/0_introduction.md
Normal file
44
docs/5_ChromiumPage/0_introduction.md
Normal file
@ -0,0 +1,44 @@
|
||||
`ChromiumPage`对象和`WebPage`对象的 d 模式,可操控浏览器。本章介绍`ChromiumPage`。
|
||||
|
||||
顾名思义,`ChromiumPage`是 Chromium 内核浏览器的页面,它用 POM 方式封装了操控网页所需的属性和方法。
|
||||
|
||||
使用它,我们可与网页进行交互,如调整窗口大小、滚动页面、操作弹出框等等。
|
||||
|
||||
通过从中获取的元素对象,我们还可以跟页面中的元素进行交互,如输入文字、点击按钮、选择下拉菜单等等。
|
||||
|
||||
甚至,我们可以在页面或元素上运行 JavaScript 代码、修改元素属性、增删元素等。
|
||||
|
||||
可以说,操控浏览器的绝大部分操作,都可以由`ChromiumPage`及其衍生的对象完成,而它们的功能,还在不断增加。
|
||||
|
||||
除了与页面和元素的交互,`ChromiumPage`还扮演着浏览器控制器的角色,可以说,一个`ChromiumPage`对象,就是一个浏览器。
|
||||
|
||||
它可以对标签页进行管理,可以对下载任务进行控制。可以为每个标签页生成独立的页面对象(`ChromiumTab`),以实现多标签页同时操作,而无须切入切出。
|
||||
|
||||
随着 3.0 版本脱离对 WebDriver 的依赖,作者终于可以放飞自我,为`ChromiumPage`添加各种各样有意思的功能,我们以后会越做越好。
|
||||
|
||||
我们看个简单的例子,来了解`CromiumPage`的工作方式。
|
||||
|
||||
---
|
||||
|
||||
在百度搜搜“Drissionpage”,并打印结果。
|
||||
|
||||
```python
|
||||
# 导入
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
# 创建对象
|
||||
page = ChromiumPage()
|
||||
# 访问网页
|
||||
page.get('https://www.baidu.com')
|
||||
# 输入文本
|
||||
page('#kw').input('DrissionPage')
|
||||
# 点击按钮
|
||||
page('#su').click()
|
||||
# 等待页面跳转
|
||||
page.wait_loading()
|
||||
# 获取所有结果
|
||||
links = page.eles('tag:h3')
|
||||
# 遍历并打印结果
|
||||
for link in links:
|
||||
print(link.text)
|
||||
```
|
@ -1,8 +1,8 @@
|
||||
参考 selenium 的`ActionChains`,本库也提供了自己的`ActionChains`。
|
||||
动作链可以在浏览器上完成一系列交互行为,如鼠标移动、鼠标点击、键盘输入等。
|
||||
|
||||
动作链可以完成一系列交互行为,如鼠标移动、鼠标点击、键盘输入等。
|
||||
动作链支持`ChromiumPage`、`WebPage`、`ChromiumTab`对象。
|
||||
|
||||
语法比 selenium 更简洁易用,每个动作执行即生效,无须`perform()`。
|
||||
可以链式操作,也可以分开执行,每个动作执行即生效,无须`perform()`。
|
||||
|
||||
多个动作可以用链式模式操作:
|
||||
|
||||
@ -28,21 +28,25 @@ ac.type('some text')
|
||||
from DrissionPage import ActionChains
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `ActionChains`
|
||||
|
||||
创建动作链对象非常简单,只要把`WebPage`对象或`ChromiumPage`对象传入即可。动作链只在这个页面上生效。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:---------------------------:|:---:| ------------ |
|
||||
| `page` | `WebPage`<br>`ChromiumPage` | 无 | 动作链要操作的浏览器页面 |
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:--------------------------------------------:|:---:| ------------ |
|
||||
| `page` | `ChromiumPage`<br>`WebPage`<br>`ChromiumTab` | 必填 | 动作链要操作的浏览器页面 |
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, ActionChains
|
||||
from DrissionPage import ChromiumPage, ActionChains
|
||||
|
||||
page = WebPage()
|
||||
ac = ActionChains(page)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔ 移动鼠标
|
||||
|
||||
## 📍 `move_to()`
|
||||
@ -51,7 +55,7 @@ ac = ActionChains(page)
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-----------------------------------------------:|:---:| --------------------------------------- |
|
||||
| `ele_or_loc` | `ChrmoiumElement`<br>`str`<br>`Tuple[int, int]` | 无 | 元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 |
|
||||
| `ele_or_loc` | `ChrmoiumElement`<br>`str`<br>`Tuple[int, int]` | 必填 | 元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 |
|
||||
| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
|
||||
| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
|
||||
|
||||
@ -66,6 +70,8 @@ ele = page('tag:a')
|
||||
ac.move_to(ele_or_loc=ele)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `move()`
|
||||
|
||||
此方法用于使鼠标相对当前位置移动若干距离。
|
||||
@ -85,13 +91,15 @@ ac.move_to(ele_or_loc=ele)
|
||||
ac.move(300, 0)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `up()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向上移动若干距离。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| -------- |
|
||||
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
|
||||
| `pixel` | `int` | 必填 | 鼠标移动的像素值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -103,13 +111,15 @@ ac.move(300, 0)
|
||||
ac.up(50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `down()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向下移动若干距离。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| -------- |
|
||||
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
|
||||
| `pixel` | `int` | 必填 | 鼠标移动的像素值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -121,13 +131,15 @@ ac.up(50)
|
||||
ac.down(50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `left()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向左移动若干距离。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| -------- |
|
||||
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
|
||||
| `pixel` | `int` | 必填 | 鼠标移动的像素值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -139,13 +151,15 @@ ac.down(50)
|
||||
ac.left(50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `right()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向右移动若干距离。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| -------- |
|
||||
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
|
||||
| `pixel` | `int` | 必填 | 鼠标移动的像素值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -157,6 +171,8 @@ ac.left(50)
|
||||
ac.right(50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔ 鼠标按键
|
||||
|
||||
## 📍 `click()`
|
||||
@ -177,6 +193,8 @@ ac.right(50)
|
||||
ac.click('#div1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `r_click()`
|
||||
|
||||
此方法用于单击鼠标右键,单击前可先移动到元素上。
|
||||
@ -195,6 +213,8 @@ ac.click('#div1')
|
||||
ac.r_click('#div1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `m_click()`
|
||||
|
||||
此方法用于单击鼠标中键,单击前可先移动到元素上。
|
||||
@ -213,6 +233,8 @@ ac.r_click('#div1')
|
||||
ac.m_click('#div1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `hold()`
|
||||
|
||||
此方法用于按住鼠标左键不放,按住前可先移动到元素上。
|
||||
@ -231,6 +253,8 @@ ac.m_click('#div1')
|
||||
ac.hold('#div1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `release()`
|
||||
|
||||
此方法用于释放鼠标左键,释放前可先移动到元素上。
|
||||
@ -249,6 +273,8 @@ ac.hold('#div1')
|
||||
ac.release('#div1')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `r_hold()`
|
||||
|
||||
此方法用于按住鼠标右键不放,按住前可先移动到元素上。
|
||||
@ -261,6 +287,8 @@ ac.release('#div1')
|
||||
|:--------------:| ------- |
|
||||
| `ActionChains` | 动作链对象本身 |
|
||||
|
||||
---
|
||||
|
||||
## 📍 `r_release()`
|
||||
|
||||
此方法用于释放鼠标右键,释放前可先移动到元素上。
|
||||
@ -273,6 +301,8 @@ ac.release('#div1')
|
||||
|:--------------:| ------- |
|
||||
| `ActionChains` | 动作链对象本身 |
|
||||
|
||||
---
|
||||
|
||||
## 📍 `m_hold()`
|
||||
|
||||
此方法用于按住鼠标中键不放,按住前可先移动到元素上。
|
||||
@ -285,6 +315,8 @@ ac.release('#div1')
|
||||
|:--------------:| ------- |
|
||||
| `ActionChains` | 动作链对象本身 |
|
||||
|
||||
---
|
||||
|
||||
## 📍 `m_release()`
|
||||
|
||||
此方法用于释放鼠标中键,释放前可先移动到元素上。
|
||||
@ -297,6 +329,8 @@ ac.release('#div1')
|
||||
|:--------------:| ------- |
|
||||
| `ActionChains` | 动作链对象本身 |
|
||||
|
||||
---
|
||||
|
||||
# ✔ 滚动滚轮
|
||||
|
||||
## 📍 `scroll()`
|
||||
@ -313,6 +347,8 @@ ac.release('#div1')
|
||||
|:--------------:| ------- |
|
||||
| `ActionChains` | 动作链对象本身 |
|
||||
|
||||
---
|
||||
|
||||
# ✔ 键盘按键
|
||||
|
||||
## 📍 `key_down()`
|
||||
@ -321,7 +357,7 @@ ac.release('#div1')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----:|:-----:|:---:| ---- |
|
||||
| `key` | `str` | 无 | 按键键值 |
|
||||
| `key` | `str` | 必填 | 按键键值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -335,13 +371,15 @@ from DrissionPage.keys import Keys
|
||||
ac.key_down(Keys.CTRL)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `key_up()`
|
||||
|
||||
此方法用于提起键盘按键,特殊字符见 Keys。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----:|:-----:|:---:| ---- |
|
||||
| `key` | `str` | 无 | 按键键值 |
|
||||
| `key` | `str` | 必填 | 按键键值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -355,13 +393,15 @@ from DrissionPage.keys import Keys
|
||||
ac.key_up(Keys.CTRL)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `type()`
|
||||
|
||||
此方法用于输入一段文本。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| ------ |
|
||||
| `text` | `str` | 无 | 要输入的文本 |
|
||||
| `text` | `str` | 必填 | 要输入的文本 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -373,6 +413,8 @@ ac.key_up(Keys.CTRL)
|
||||
ac.type('text')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔ 等待
|
||||
|
||||
## 📍 `wait()`
|
||||
@ -381,7 +423,7 @@ ac.type('text')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:-------:|:---:| ---- |
|
||||
| `second` | `float` | 无 | 等待秒数 |
|
||||
| `second` | `float` | 必填 | 等待秒数 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:--------------:| ------- |
|
||||
@ -393,6 +435,8 @@ ac.type('text')
|
||||
ac.wait(3)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔ 示例
|
||||
|
||||
## 📍 模拟输入 ctrl+a
|
||||
@ -423,6 +467,8 @@ ac.key_up(Keys.CTRL)
|
||||
ac.click('tag:input').key_down(Keys.CTRL).type('a').key_up(Keys.CTRL)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 拖拽元素
|
||||
|
||||
把一个元素向右拖拽 300 像素:
|
@ -10,6 +10,8 @@
|
||||
from DrissionPage import ChromiumOptions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `ChromiumOptions`
|
||||
|
||||
`ChromiumOptions`对象用于管理浏览器初始化配置。可从配置文件中读取配置来进行初始化。
|
||||
@ -29,7 +31,7 @@ co = ChromiumOptions()
|
||||
|
||||
默认情况下,`ChromiumOptions`对象会从 ini 文件中读取配置信息,当指定`read_file`参数为`False`时,则以默认配置创建。
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 使用方法
|
||||
|
||||
@ -47,7 +49,7 @@ co.set_no_imgs(True).set_mute(True)
|
||||
page = WebPage(driver_or_options=co)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 启动参数配置
|
||||
|
||||
@ -63,7 +65,7 @@ Chromium 内核浏览器有一系列的启动配置,以`--`开头,可在浏
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:--------------------------:|:------:| ------------------------------------------------- |
|
||||
| `arg` | `str` | 无 | 启动参数名称 |
|
||||
| `arg` | `str` | 必填 | 启动参数名称 |
|
||||
| `value` | `str`<br>`None`<br>`False` | `None` | 参数的值。带值的参数传入属性值,没有的传入`None`。<br>如传入`False`,删除该参数。 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
@ -79,7 +81,7 @@ co.set_argument('--headless')
|
||||
co.set_argument('--user-agent', 'Mozilla/5.0 (Macintos.....')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `remove_argument()`
|
||||
|
||||
@ -87,7 +89,7 @@ co.set_argument('--user-agent', 'Mozilla/5.0 (Macintos.....')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----:|:-----:|:---:| ------------------- |
|
||||
| `arg` | `str` | 无 | 参数名称,有值的设置项传入设置名称即可 |
|
||||
| `arg` | `str` | 必填 | 参数名称,有值的设置项传入设置名称即可 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -102,7 +104,7 @@ co.remove_argument('--headless')
|
||||
co.remove_argument('--user-agent')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 插件配置
|
||||
|
||||
@ -114,7 +116,7 @@ co.remove_argument('--user-agent')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:---------------:|:---:| ---- |
|
||||
| `path` | `str`<br>`Path` | 无 | 插件路径 |
|
||||
| `path` | `str`<br>`Path` | 必填 | 插件路径 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -128,7 +130,7 @@ co.remove_argument('--user-agent')
|
||||
co.add_extension(r'D:\SwitchyOmega')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `remove_extensions()`
|
||||
|
||||
@ -142,7 +144,7 @@ co.add_extension(r'D:\SwitchyOmega')
|
||||
co.remove_extensions()
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 用户文件配置
|
||||
|
||||
@ -166,7 +168,7 @@ Chromium 浏览器支持多用户配置,我们可以选择使用哪一个。
|
||||
co.set_user(user='Profile 1')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_pref()`
|
||||
|
||||
@ -176,8 +178,8 @@ co.set_user(user='Profile 1')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| ----- |
|
||||
| `arg` | `str` | 无 | 设置项名称 |
|
||||
| `value` | `str` | 无 | 设置项值 |
|
||||
| `arg` | `str` | 必填 | 设置项名称 |
|
||||
| `value` | `str` | 必填 | 设置项值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -189,7 +191,7 @@ co.set_user(user='Profile 1')
|
||||
co.set_pref(arg='profile.default_content_settings.popups', value='0')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `remove_pref()`
|
||||
|
||||
@ -197,7 +199,7 @@ co.set_pref(arg='profile.default_content_settings.popups', value='0')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----:|:-----:|:---:| ----- |
|
||||
| `arg` | `str` | 无 | 设置项名称 |
|
||||
| `arg` | `str` | 必填 | 设置项名称 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -209,7 +211,7 @@ co.set_pref(arg='profile.default_content_settings.popups', value='0')
|
||||
co.remove_pref(arg='profile.default_content_settings.popups')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `remove_pref_from_file()`
|
||||
|
||||
@ -217,7 +219,7 @@ co.remove_pref(arg='profile.default_content_settings.popups')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----:|:-----:|:---:| ----- |
|
||||
| `arg` | `str` | 无 | 设置项名称 |
|
||||
| `arg` | `str` | 必填 | 设置项名称 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -229,7 +231,7 @@ co.remove_pref(arg='profile.default_content_settings.popups')
|
||||
co.remove_pref_from_file(arg='profile.default_content_settings.popups')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 运行参数配置
|
||||
|
||||
@ -258,7 +260,7 @@ co.remove_pref_from_file(arg='profile.default_content_settings.popups')
|
||||
co.set_paths(local_port=9333, user_data_path=r'D:\tmp')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `auto_port()`
|
||||
|
||||
@ -284,7 +286,7 @@ co.auto_port(True)
|
||||
|
||||
!>**注意:**<br>启用此功能后即会获取端口和新建临时用户数据文件夹,若此时用`save()`方法保存配置到 ini 文件,ini 文件中的设置会被该端口和文件夹路径覆盖。这个覆盖对使用并没有很大影响。
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_timeouts()`
|
||||
|
||||
@ -306,7 +308,7 @@ co.auto_port(True)
|
||||
co.set_timeouts(implicit=10)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_page_load_strategy()`
|
||||
|
||||
@ -326,7 +328,7 @@ co.set_timeouts(implicit=10)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| -------------------------------- |
|
||||
| `value` | `str` | 无 | 可接收`'normal'`、`'eager'`、`'none'` |
|
||||
| `value` | `str` | 必填 | 可接收`'normal'`、`'eager'`、`'none'` |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -338,7 +340,7 @@ co.set_timeouts(implicit=10)
|
||||
co.set_page_load_strategy('eager')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_proxy()`
|
||||
|
||||
@ -346,7 +348,7 @@ co.set_page_load_strategy('eager')
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| --------------------------------------- |
|
||||
| `proxy` | `str` | 无 | 格式:协议://ip:port<br>当不指定协议时,默认使用 http 代理 |
|
||||
| `proxy` | `str` | 必填 | 格式:协议://ip:port<br>当不指定协议时,默认使用 http 代理 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -358,7 +360,7 @@ co.set_page_load_strategy('eager')
|
||||
co.set_proxy('http://localhost:1080')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 其它配置
|
||||
|
||||
@ -384,7 +386,7 @@ co.set_headless(True)
|
||||
|
||||
!>**注意:**<br>经实测,Chrome 使用无界面模式时,由 js 生成的元素可能不能加载。
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_no_imgs()`
|
||||
|
||||
@ -404,7 +406,7 @@ co.set_headless(True)
|
||||
co.set_no_imgs(True)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_no_js()`
|
||||
|
||||
@ -424,7 +426,7 @@ co.set_no_imgs(True)
|
||||
co.set_no_js(True)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_mute()`
|
||||
|
||||
@ -444,7 +446,7 @@ co.set_no_js(True)
|
||||
co.set_mute(True)
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_user_agent()`
|
||||
|
||||
@ -452,7 +454,7 @@ co.set_mute(True)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-----:|:---:| ------------ |
|
||||
| `user_agent` | `str` | 无 | user agent文本 |
|
||||
| `user_agent` | `str` | 必填 | user agent文本 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
| ----------------- | ------ |
|
||||
@ -464,7 +466,7 @@ co.set_mute(True)
|
||||
co.set_user_agent(user_agent='Mozilla/5.0 (Macintos.....')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ 保存设置到文件
|
||||
|
||||
@ -492,7 +494,7 @@ co.save()
|
||||
co.save(path=r'D:\tmp\settings.ini')
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `save_to_default()`
|
||||
|
||||
@ -510,7 +512,7 @@ co.save(path=r'D:\tmp\settings.ini')
|
||||
co.save_to_default()
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
# ✔️ `ChromiumOptions`属性
|
||||
|
||||
@ -524,7 +526,7 @@ co.save_to_default()
|
||||
co.debugger_address = 'localhost:9333'
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `browser_path`
|
||||
|
||||
@ -532,7 +534,7 @@ co.debugger_address = 'localhost:9333'
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `user_data_path`
|
||||
|
||||
@ -540,7 +542,7 @@ co.debugger_address = 'localhost:9333'
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `download_path`
|
||||
|
||||
@ -548,7 +550,7 @@ co.debugger_address = 'localhost:9333'
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `user`
|
||||
|
||||
@ -556,7 +558,7 @@ co.debugger_address = 'localhost:9333'
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `page_load_strategy`
|
||||
|
||||
@ -564,7 +566,7 @@ co.debugger_address = 'localhost:9333'
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `timeouts`
|
||||
|
||||
@ -576,7 +578,7 @@ co.debugger_address = 'localhost:9333'
|
||||
print(co.timeouts)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
{
|
||||
@ -586,7 +588,7 @@ print(co.timeouts)
|
||||
}
|
||||
```
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `proxy`
|
||||
|
||||
@ -594,7 +596,7 @@ print(co.timeouts)
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `arguments`
|
||||
|
||||
@ -602,7 +604,7 @@ print(co.timeouts)
|
||||
|
||||
**类型:**`list`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `extensions`
|
||||
|
||||
@ -610,12 +612,10 @@ print(co.timeouts)
|
||||
|
||||
**类型:**`list`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `preferences`
|
||||
|
||||
该属性返回用户首选项配置。
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
***
|
239
docs/5_ChromiumPage/1_create_page_object.md
Normal file
239
docs/5_ChromiumPage/1_create_page_object.md
Normal file
@ -0,0 +1,239 @@
|
||||
`ChromiumPage`对象和`WebPage`对象的 d 模式都能收发数据包,本节只介绍`ChromiumPage`的创建,在`WebPage`的章节再对其进行介绍。
|
||||
|
||||
# ✔️ `ChromiumPage`初始化参数
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:------------------:|:---------------------------------------------------:|:------:| ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `addr_driver_opts` | `str`<br>`ChrromiumDriver`<br>`ChromiumOptions`<br> | `None` | 浏览器启动配置或接管信息。<br>传入`ChromiumDriver`对象时接管浏览器;<br>传入 ' ip: port' 字符串或`ChromiumOptions`对象时按配置启动或接管浏览器;<br>为`None`时使用配置文件配置启动浏览器 |
|
||||
| `tab_id` | `str` | `None` | 要控制的标签页 id,为`None`则控制激活的标签页 |
|
||||
| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取,默认 10 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 直接创建
|
||||
|
||||
这种方式代码最简洁,程序会从默认 ini 文件中读取配置,自动生成页面对象。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
```
|
||||
|
||||
创建`ChromiumPage`对象时会在指定端口启动浏览器,或接管该端口已有浏览器。
|
||||
|
||||
默认情况下,程序使用 9222 端口,浏览器可执行文件路径为`'chrome'`。如路径中没找到浏览器可执行文件,Windows 系统下程序会在注册表中查找路径。
|
||||
|
||||
如果都没找到,则要用下一种方式手动配置。
|
||||
|
||||
!>**注意:**<br>这种方式的程序不能直接打包,因为使用到 ini 文件。可参考“打包程序”一节的方法。
|
||||
|
||||
?>**Tips:**<br>您可以修改配置文件中的配置,实现所有程序都按您的须要进行启动,详见”启动配置“章节。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 通过配置信息创建
|
||||
|
||||
如果须要已指定方式启动浏览器,可使用`ChromiumOptions`。它是专门用于设置浏览器初始状态的类,内置了常用的配置。详细使用方法见“浏览器启动配置”一节。
|
||||
|
||||
## 📍 使用方法
|
||||
|
||||
`ChromiumOptions`用于管理创建浏览器时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| ----------- | ------ | ------ | ------------------------------------ |
|
||||
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息,如果为`False`则用默认配置创建 |
|
||||
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
|
||||
|
||||
!>**注意:**<br>- 配置对象只有在启动浏览器时生效。<br>- 浏览器创建后再修改这个配置是没有效果的。<br>- 接管已打开的浏览器配置也不会生效。
|
||||
|
||||
```python
|
||||
# 导入 ChromiumOptions
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
# 创建浏览器配置对象,指定浏览器路径
|
||||
do = ChromiumOptions().set_paths(browser_path=r'D:\chrome.exe')
|
||||
# 用该配置创建页面对象
|
||||
page = WebPage(addr_driver_opts=do)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 直接指定地址创建
|
||||
|
||||
`ChromiumPage`可以直接接收浏览器地址来创建,格式为 'ip:port'。
|
||||
|
||||
使用这种方式时,如果浏览器已存在,程序会直接接管;如不存在,程序会读取默认配置文件配置,在指定端口启动浏览器。
|
||||
|
||||
```python
|
||||
page = ChromiumPage(addr_driver_opts='127.0.0.1:9333')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 使用指定 ini 文件创建
|
||||
|
||||
以上方法是使用默认 ini 文件中保存的配置信息创建对象,你可以保存一个 ini 文件到别的地方,并在创建对象时指定使用它。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptinos
|
||||
|
||||
# 创建配置对象时指定要读取的ini文件路径
|
||||
co = ChromiumOptinos(ini_path=r'./config1.ini')
|
||||
# 使用该配置对象创建页面
|
||||
page = ChromiumPage(addr_driver_opts=co)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 传递控制权
|
||||
|
||||
当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
|
||||
|
||||
这可以实现多个页面对象共同控制一个浏览器。
|
||||
|
||||
```python
|
||||
# 创建一个页面
|
||||
page1 = ChormiumPage()
|
||||
# 获取页面对象的浏览器控制器
|
||||
driver = page1.driver
|
||||
# 把控制器对象在第二个页面对象初始化时传递进去
|
||||
page2 = ChormiumPage(driver_or_options=driver)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 接管已打开的浏览器
|
||||
|
||||
页面对象创建时,只要指定的地址(ip: port)已有浏览器在运行,就会直接接管。无论浏览器是下面哪种方式启动的。
|
||||
|
||||
## 📍 用程序启动的浏览器
|
||||
|
||||
默认情况下,创建浏览器页面对象时会自动启动一个浏览器。只要这个浏览器不关闭,下次运行程序时会接管同一个浏览器继续操作(配置的 ip: port 信息不变)。
|
||||
|
||||
这种方式极大地方便了程序的调试,使程序不必每次重新开始,可以单独调试某个功能。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
# 创建对象同时启动浏览器,如果浏览器已经存在,则接管它
|
||||
page = ChromiumPage()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 手动打开的浏览器
|
||||
|
||||
如果须要手动打开浏览器再接管,可以这样做:
|
||||
|
||||
- 右键点击浏览器图标,选择属性
|
||||
|
||||
- 在“目标”路径后面加上` --remote-debugging-port=端口号`(注意最前面有个空格)
|
||||
|
||||
- 点击确定
|
||||
|
||||
- 在程序中的浏览器配置中指定接管该端口浏览器
|
||||
|
||||
文件快捷方式的目标路径设置:
|
||||
|
||||
```
|
||||
D:\chrome.exe --remote-debugging-port=9222
|
||||
```
|
||||
|
||||
程序代码:
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
co = ChromiumOptions().set_paths(local_port=9222)
|
||||
page = ChromiumPage(addr_driver_opts=co)
|
||||
```
|
||||
|
||||
!> **注意:**<br>接管浏览器时只有`local_port`、`debugger_address`参数是有效的。
|
||||
|
||||
---
|
||||
|
||||
## 📍 bat 文件启动的浏览器
|
||||
|
||||
可以把上一种方式的目标路径设置写进 bat 文件(Windows系统),运行 bat 文件来启动浏览器,再用程序接管。
|
||||
|
||||
新建一个文本文件,在里面输入以下内容(路径改为自己电脑的):
|
||||
|
||||
```console
|
||||
"D:\chrome.exe" --remote-debugging-port=9222
|
||||
```
|
||||
|
||||
保存后把后缀改成 bat,然后双击运行就能在 9222 端口启动一个浏览器。程序代码则和上一个方法一致。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 多浏览器共存
|
||||
|
||||
如果想要同时操作多个浏览器,或者自己在使用其中一个上网,同时控制另外几个跑自动化,就须要给这些被程序控制的浏览器设置单独的**端口**和**用户文件夹**,否则会造成冲突。
|
||||
|
||||
## 📍 指定独立端口和数据文件夹
|
||||
|
||||
每个要启动的浏览器使用一个独立的`ChromiumOptions`对象进行设置:
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
# 创建多个配置对象,每个指定不同的端口号和用户文件夹路径
|
||||
do1 = ChromiumOptions().set_paths(local_port=9111, user_data_path=r'D:\data1')
|
||||
do2 = ChromiumOptions().set_paths(local_port=9222, user_data_path=r'D:\data2')
|
||||
|
||||
# 创建多个页面对象
|
||||
page1 = ChromiumPage(addr_driver_opts=do1)
|
||||
page2 = ChromiumPage(addr_driver_opts=do2)
|
||||
|
||||
# 每个页面对象控制一个浏览器
|
||||
page1.get('https://www.baidu.com')
|
||||
page2.get('http://www.163.com')
|
||||
```
|
||||
|
||||
?>**Tips:**<br>每个浏览器都要设置独立的端口号和用户文件夹,二者缺一不可。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `auto_port()`方法
|
||||
|
||||
`ChromiumOptions`对象的`auto_port()`方法,可以指定程序每次使用空闲的端口和临时用户文件夹创建浏览器。也是每个浏览器要使用独立的`ChromiumOptions`对象。
|
||||
|
||||
但这种方法创建的浏览器不能重复使用。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
co1 = ChromiumOptions().auto_port()
|
||||
co2 = ChromiumOptions().auto_port()
|
||||
|
||||
page1 = ChromiumPage(addr_driver_opts=co1)
|
||||
page2 = ChromiumPage(addr_driver_opts=co2)
|
||||
|
||||
page1.get('https://www.baidu.com')
|
||||
page2.get('http://www.163.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 在 ini 文件设置使用自动分配
|
||||
|
||||
可以把自动分配的配置记录到 ini 文件,这样无须创建`ChromiumOptions`,每次启动的浏览器都是独立的,不会冲突。但和`auto_port()`一样,这些浏览器也不能复用。
|
||||
|
||||
```python
|
||||
from DrissionPage.easy_set import use_auto_port
|
||||
|
||||
use_auto_port(True)
|
||||
```
|
||||
|
||||
这段代码把记录该配置到 ini 文件,只需运行一次,要关闭的话把参数换成`False`再执行一次即可。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page1 = ChromiumPage()
|
||||
page2 = ChromiumPage()
|
||||
|
||||
page1.get('https://www.baidu.com')
|
||||
page2.get('http://www.163.com')
|
||||
```
|
62
docs/5_ChromiumPage/2_visit_web_page.md
Normal file
62
docs/5_ChromiumPage/2_visit_web_page.md
Normal file
@ -0,0 +1,62 @@
|
||||
`ChromiumPage`对象和`WebPage`对象的 d 模式都能控制浏览器访问网页。这里只对`ChromiumPage`进行说明,后面章节再单独介绍`WebPage`。
|
||||
|
||||
# ✔️ `get()`
|
||||
|
||||
该方法用于跳转到一个网址。当连接失败时,程序会进行重试。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:----------------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 必填 | 目标 url |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `int`<br>`float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 加载超时时间(秒) |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 设置超时和重试
|
||||
|
||||
网络不稳定时访问页面不一定成功,`get()`方法内置了超时和重试功能。通过`retry`、`interval`、`timeout`三个参数进行设置。
|
||||
其中,如不指定`timeout`参数,该参数会使用`ChromiumPage`的`timeouts`属性的`page_load`参数中的值。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.get('https://www.163.com', retry=1, interval=1, timeout=1.5)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 设置加载策略
|
||||
|
||||
通过设置`ChromiumPage`对象的`page_load_strategy`属性,可设置页面停止加载的时机。页面加载时,在到达超时时间,或达到设定的状态,就会停止,可有效节省采集时间。有以下三种模式:
|
||||
|
||||
- `'normal'`:常规模式,会等待页面加载完毕
|
||||
|
||||
- `'eager'`:加载完 DOM 即停止加载
|
||||
|
||||
- `'none'`:完成连接即停止加载
|
||||
|
||||
默认设置为`'normal'`。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.set_page_load_strategy('eager')
|
||||
page.get('https://www.163.com')
|
||||
```
|
320
docs/5_ChromiumPage/3_get_page_info.md
Normal file
320
docs/5_ChromiumPage/3_get_page_info.md
Normal file
@ -0,0 +1,320 @@
|
||||
成功访问网页后,可使用`ChromiumPage`自身属性和方法获取页面信息。
|
||||
|
||||
操控浏览器除了`ChromiumPage`,还有`ChromiumTab`和`ChromiumFrame`两种页面对象分别对应于标签页对象和`<iframe>`元素对象,后面会有单独章节介绍。
|
||||
|
||||
# ✔️ 运行状态信息
|
||||
|
||||
## 📍 `url`
|
||||
|
||||
此属性返回当前访问的 url。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `address`
|
||||
|
||||
此属性返回当前对象控制的页面地址和端口。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
```python
|
||||
print(page.address)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```
|
||||
127.0.0.1:9222
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `tab_id`
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
此属性返回当前标签页的 id。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `process_id`
|
||||
|
||||
此属性返回浏览器进程 id。
|
||||
|
||||
**返回类型:**`int`、`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_loading`
|
||||
|
||||
此属性返回页面是否正在加载状态。
|
||||
|
||||
**返回类型:**`bool`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `ready_state`
|
||||
|
||||
此属性返回页面当前加载状态,有 3 种:
|
||||
|
||||
- `'loading'`:表示文档还在加载中
|
||||
|
||||
- `'interactive'`:DOM 已加载,但资源未加载完成
|
||||
|
||||
- `'complete'`:所有内容已完成加载
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `url_available`
|
||||
|
||||
此属性以布尔值返回当前链接是否可用。
|
||||
|
||||
**返回类型:**`bool`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 窗口及页面信息
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
此属性以`tuple`返回页面尺寸,格式:(宽, 高)。
|
||||
|
||||
**返回类型:**`Tuple[int, int]`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `tabs_count`
|
||||
|
||||
此属性返回当前浏览器标签页数量。
|
||||
|
||||
**返回类型:**`int`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `tabs`
|
||||
|
||||
此属性以列表形式返回当前浏览器所有标签页 id。
|
||||
|
||||
**返回类型:**`List[str]`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回当前页面 html 文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `json`
|
||||
|
||||
此属性把请求内容解析成 json。
|
||||
|
||||
假如用浏览器访问会返回 json 数据的 url,浏览器会把 json 数据显示出来,这个参数可以把这些数据转换为`dict`格式。
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `title`
|
||||
|
||||
此属性返回当前页面`title`文本。
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 配置参数信息
|
||||
|
||||
## 📍 `timeout`
|
||||
|
||||
此属性为整体默认超时时间,包括元素查找、点击、处理提示框、列表选择等须要用到超时设置的地方,都以这个数据为默认值。
|
||||
默认为 10,可对其赋值。
|
||||
|
||||
**返回类型:**`int`、`float`
|
||||
|
||||
```python
|
||||
# 创建页面对象时指定
|
||||
page = ChromiumPage(timeout=5)
|
||||
|
||||
# 修改 timeout
|
||||
page.timeout = 20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `timeouts`
|
||||
|
||||
此属性以字典方式返回三种超时时间。
|
||||
|
||||
- `'implicit'`:与`timeout`属性是同一个值
|
||||
|
||||
- `'page_load'`:用于等待页面加载
|
||||
|
||||
- `'script'`:用于等待脚本执行
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
```python
|
||||
print(page.timeouts)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'implicit': 10, 'pageLoad': 30.0, 'script': 30.0}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `retry_times`
|
||||
|
||||
此属性为网络连接失败时的重试次数。默认为 3,可对其赋值。
|
||||
|
||||
**返回类型:**`int`
|
||||
|
||||
```python
|
||||
# 修改重试次数
|
||||
page.retry_times = 5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `retry_interval`
|
||||
|
||||
此属性为网络连接失败时的重试等待间隔秒数。默认为 2,可对其赋值。
|
||||
|
||||
**返回类型:**`int`、`float`
|
||||
|
||||
```python
|
||||
# 修改重试等待间隔时间
|
||||
page.retry_interval = 1.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `page_load_strategy`
|
||||
|
||||
此属性返回页面加载策略,有 3 种:
|
||||
|
||||
- `'normal'`:等待页面所有资源完成加载
|
||||
|
||||
- `'eager'`:DOM 加载完成即停止
|
||||
|
||||
- `'none'`:页面完成连接即停止
|
||||
|
||||
**返回类型:**`str`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ cookies 和缓存信息
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
此属性以`dict`方式返回当前页面所使用的 cookies。
|
||||
|
||||
**返回类型:**`dict`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get_cookies()`
|
||||
|
||||
此方法获取 cookies 并以 cookie 组成的`list`形式返回。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| --------------------------------------- |
|
||||
| `as_dict` | `bool` | `False` | 是否以字典方式返回结果,为`False`返回 cookie 组成的`list` |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------- |
|
||||
| `dict` | cookies 字典 |
|
||||
| `list` | cookies 组成的列表 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
p = ChromiumPage()
|
||||
p.get('http://www.baidu.com')
|
||||
|
||||
for i in p.get_cookies(as_dict=False):
|
||||
print(i)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'domain': '.baidu.com', 'domain_specified': True, ......}
|
||||
......
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get_session_storage()`
|
||||
|
||||
此方法用于获取 sessionStorage 信息,可获取全部或单个项。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:------:| -------------------------- |
|
||||
| `item` | `str` | `None` | 要获取的项目,为`None`则返回全部项目组成的字典 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ---------------------- |
|
||||
| `dict` | `item`参数为`None`时返回所有项目 |
|
||||
| `str` | 指定`item`时返回该项目内容 |
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get_local_storage()`
|
||||
|
||||
此方法用于获取 localStorage 信息,可获取全部或单个项。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:------:| -------------------------- |
|
||||
| `item` | `str` | `None` | 要获取的项目,为`None`则返回全部项目组成的字典 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ---------------------- |
|
||||
| `dict` | `item`参数为`None`时返回所有项目 |
|
||||
| `str` | 指定`item`时返回该项目内容 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 内嵌对象
|
||||
|
||||
## 📍 `driver`
|
||||
|
||||
此属性返回当前页面对象使用的`ChromiumDriver`对象。
|
||||
|
||||
**返回类型:**`ChromiumDriver`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 页面截图
|
||||
|
||||
## 📍 `get_screenshot()`
|
||||
|
||||
此方法用于对页面进行截图,可对整个网页、可见网页、指定范围截图。对可视范围外截图需要 90 以上版本浏览器支持。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------------:|:-------------------------:|:-------:| --------------------------------------------------------------------------------------------------------- |
|
||||
| `path` | `str`<br>`Path`<br>`None` | `None` | 保存图片的完整路径,文件后缀可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`<br>为`None`时以 jpg 格式保存在当前文件夹 |
|
||||
| `as_bytes` | `str`<br>`None`<br>`True` | `None` | 是否已字节形式返回图片,可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`、`None`、`True`<br>不为`None`时`path`参数无效<br>为`True`时选用 jpg 格式 |
|
||||
| `full_page` | `bool` | `False` | 是否整页截图,为`True`截取整个网页,为`False`截取可视窗口 |
|
||||
| `left_top` | `Tuple[int, int]` | `None` | 截取范围左上角坐标 |
|
||||
| `right_bottom` | `Tuple[int, int]` | `None` | 截取范围右下角坐标 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-------:| -------------------------- |
|
||||
| `bytes` | `as_bytes`生效时返回图片字节 |
|
||||
| `str` | `as_bytes`为`None`时返回图片完整路径 |
|
||||
|
||||
```python
|
||||
# 对整页截图并保存
|
||||
page.get_screenshot(path='D:\\page.png', full_page=True)
|
||||
```
|
506
docs/5_ChromiumPage/4_page_operation.md
Normal file
506
docs/5_ChromiumPage/4_page_operation.md
Normal file
@ -0,0 +1,506 @@
|
||||
本节介绍浏览器页面交互功能,元素的交互在下一节。
|
||||
|
||||
页面对象包括`ChromiumPage`、d 模式的`WebPage`、`ChromiumTab`、`ChromiumFrame`几种,这里只介绍`ChromiumPage`,其它几种后面专门章节介绍。
|
||||
|
||||
# ✔️ 页面跳转
|
||||
|
||||
## 📍 `get()`
|
||||
|
||||
该方法用于跳转到一个网址。当连接失败时,程序会进行重试。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:----------------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 必填 | 目标 url |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `int`<br>`float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 加载超时时间(秒) |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------ |
|
||||
| `bool` | 是否连接成功 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `back()`
|
||||
|
||||
此方法用于在浏览历史中后退若干步。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| ---- |
|
||||
| `steps` | `int` | `1` | 后退步数 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.back(2) # 后退两个网页
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `forward()`
|
||||
|
||||
此方法用于在浏览历史中前进若干步。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| ---- |
|
||||
| `steps` | `int` | `1` | 前进步数 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.forward(2) # 前进两步
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `refresh()`
|
||||
|
||||
此方法用于刷新当前页面。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------------:|:------:|:-------:| --------- |
|
||||
| `ignore_cache` | `bool` | `False` | 刷新时是否忽略缓存 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.refresh() # 刷新页面
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `stop_loading()`
|
||||
|
||||
此方法用于强制停止当前页面加载。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `wait_loading()`
|
||||
|
||||
此方法用于等待页面进入加载状态。
|
||||
|
||||
我们经常会通过点击页面元素进入下一个网页,并立刻获取新页面的元素。但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。使用此方法,会阻塞程序,等待页面开始加载后再继续,从而避免上述问题。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------------------------------------:|:------:| ------------------------------------------------- |
|
||||
| `timeout` | `int`<br>`float`<br>`None`<br>`True` | `None` | 超时时间,为`None`或`Ture`时使用页面`timeout`设置<br>为数字时等待相应时间 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------- |
|
||||
| `bool` | 等待结束时是否进入加载状态 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.click() # 点击某个元素
|
||||
page.wait_loading() # 等待页面进入加载状态
|
||||
# 执行在新页面的操作
|
||||
print(page.title)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 执行脚本或命令
|
||||
|
||||
## 📍 `run_js()`
|
||||
|
||||
此方法用于执行 js 脚本。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| ----------------------------------------------- |
|
||||
| `script` | `str` | 必填 | js 脚本文本 |
|
||||
| `as_expr` | `bool` | `False` | 是否作为表达式运行,为`True`时`args`参数无效 |
|
||||
| `*args` | - | 无 | 传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`... |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----:| ------ |
|
||||
| `Any` | 脚本执行结果 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 用传入参数的方式执行 js 脚本显示弹出框显示 Hello world!
|
||||
page.run_js('alert(arguments[0]+arguments[1]);', 'Hello', ' world!')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `run_async_script()`
|
||||
|
||||
此方法用于以异步方式执行 js 代码。
|
||||
|
||||
**参数:**
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| ----------------------------------------------- |
|
||||
| `script` | `str` | 必填 | js 脚本文本 |
|
||||
| `as_expr` | `bool` | `False` | 是否作为表达式运行,为`True`时`args`参数无效 |
|
||||
| `*args` | - | 无 | 传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`... |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `run_cdp()`
|
||||
|
||||
此方法用于执行 Chrome DevTools Protocol 语句。
|
||||
|
||||
cdp 用法详见 [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-----:|:---:| ---- |
|
||||
| `cmd` | `str` | 必填 | 协议项目 |
|
||||
| `**cmd_args` | - | 无 | 项目参数 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------- |
|
||||
| `dict` | 执行返回的结果 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 停止页面加载
|
||||
page.run_cdp('Page.stopLoading')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ cookies 及缓存
|
||||
|
||||
## 📍 `set_cookies()`
|
||||
|
||||
此方法用于设置 cookies。
|
||||
|
||||
可以接收`CookieJar`、`list`、`tuple`、`str`、`dict`格式的 cookies。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:-----------------------------------------------------------:|:---:| ---------- |
|
||||
| `cookies` | `RequestsCookieJar`<br>`list`<br>`tuple`<br>`str`<br>`dict` | 必填 | cookies 信息 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
cookies = {'name': 'abc'}
|
||||
page.set_cookies(cookies, set_session=True, set_driver=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_session_storage()`
|
||||
|
||||
此方法用于设置或删除某项 sessionStorage 信息。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:----------------:|:---:| -------------- |
|
||||
| `item` | `str` | 必填 | 要设置的项 |
|
||||
| `value` | `str`<br>`False` | 必填 | 为`False`时,删除该项 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.set_session_storage(item='abc', value='123')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_local_storage()`
|
||||
|
||||
此方法用于设置或删除某项 localStorage 信息。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:----------------:|:---:| -------------- |
|
||||
| `item` | `str` | 必填 | 要设置的项 |
|
||||
| `value` | `str`<br>`False` | 必填 | 为`False`时,删除该项 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `clear_cache()`
|
||||
|
||||
此方法用于清除缓存,可选择要清除的项。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----------------:|:------:|:------:| ------------------- |
|
||||
| `session_storage` | `bool` | `True` | 是否清除 sessionstorage |
|
||||
| `local_storage` | `bool` | `True` | 是否清除 localStorage |
|
||||
| `cache` | `bool` | `True` | 是否清除 cache |
|
||||
| `cookies` | `bool` | `True` | 是否清除 cookies |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.clear_cache(cookies=False) # 除了 cookies,其它都清除
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 各种设置
|
||||
|
||||
## 📍 `set_timeouts()`
|
||||
|
||||
此方法用于设置三种超时时间,单位为秒。可单独设置,为`None`表示不改变原来设置。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----------:|:--------------------------:|:------:| -------- |
|
||||
| `implicit` | `int`<br>`float`<br>`None` | `None` | 整体超时时间 |
|
||||
| `page_load` | `int`<br>`float`<br>`None` | `None` | 页面加载超时时间 |
|
||||
| `script` | `int`<br>`float`<br>`None` | `None` | 脚本运行超时时间 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.set_timeouts(implicit=10, page_load=30)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_page_load_strategy`
|
||||
|
||||
此属性用于设置页面加载策略,调用其方法选择某种策略。
|
||||
|
||||
| 方法名称 | 参数 | 说明 |
|
||||
|:----------:|:---:| ------------------- |
|
||||
| `normal()` | 无 | 等待页面完全加载完成,为默认状态 |
|
||||
| `eager()` | 无 | 等待文档加载完成就结束,不等待资源加载 |
|
||||
| `none()` | 无 | 页面连接完成就结束 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.set_page_load_strategy.normal()
|
||||
page.set_page_load_strategy.eager()
|
||||
page.set_page_load_strategy.none()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_ua_to_tab()`
|
||||
|
||||
此方法用于为浏览器当前标签页设置 user agent,只在当前 tab 有效。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----:|:-----:|:---:| -------------- |
|
||||
| `ua` | `str` | 必填 | user agent 字符串 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_headers()`
|
||||
|
||||
此方法用于设置额外添加到当前页面请求 headers 的参数。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:---:| ----------------- |
|
||||
| `headers` | `dict` | 必填 | `dict`形式的 headers |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
h = {'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'}
|
||||
page.set_headers(headers=h)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 窗口管理
|
||||
|
||||
## 📍 调整大小和位置
|
||||
|
||||
`set_window`属性返回一个`WindowSetter`对象,调用其方法执行改变窗口状态。
|
||||
|
||||
| 方法 | 参数 | 说明 |
|
||||
|:---------------------:|:----------------:| ---- |
|
||||
| `maximized()` | 无 | 最大化 |
|
||||
| `minimized()` | 无 | 最小化 |
|
||||
| `fullscreen()` | 无 | 全屏 |
|
||||
| `normal()` | 无 | 常规 |
|
||||
| `size(width, height)` | 宽,高 | 设置大小 |
|
||||
| `location(x, y)` | 屏幕坐标,左上角为 (0, 0) | 设置位置 |
|
||||
|
||||
```python
|
||||
# 窗口最大化
|
||||
page.set_window.maximized()
|
||||
|
||||
# 窗口全屏,即 F11
|
||||
page.set_window.fullscreen()
|
||||
|
||||
# 恢复普通窗口
|
||||
page.set_window.normal()
|
||||
|
||||
# 设置窗口大小
|
||||
page.set_window.size(500, 500)
|
||||
|
||||
# 设置窗口位置
|
||||
page.set_window.location(200, 200)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 隐藏和显示窗口
|
||||
|
||||
`hide_browser()`和`show_browser()`方法用于随时隐藏和显示浏览器窗口。
|
||||
|
||||
与 headless 模式不一样,这两个方法是直接隐藏和显示浏览器进程。在任务栏上也会消失。
|
||||
|
||||
只支持 Windows 系统,并且必须已安装 pypiwin32 库才可使用。
|
||||
|
||||
🔸 `hide_browser()`
|
||||
|
||||
此方法用于隐藏当前浏览器窗口。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
🔸 `show_browser()`
|
||||
|
||||
此方法用于显示当前浏览器窗口。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.hide_browser()
|
||||
```
|
||||
|
||||
!>**注意:**<br>- 浏览器隐藏后并没有关闭,下次运行程序还会接管已隐藏的浏览器<br>- 浏览器隐藏后,如果有新建标签页,会自行显示出来
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 滚动页面
|
||||
|
||||
## 📍 `scroll`
|
||||
|
||||
此属性用于以某种方式滚动页面。
|
||||
调用时返回一个`Scroll`对象,调用其方法实现页面各种方式的滚动。
|
||||
|
||||
| 方法 | 参数 | 功能 |
|
||||
| ------------------- | ------------------- | ---------------- |
|
||||
| `to_top()` | 无 | 滚动到顶端,水平位置不变 |
|
||||
| `to_bottom()` | 无 | 滚动到底端,水平位置不变 |
|
||||
| `to_half()` | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| `to_rightmost()` | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| `to_leftmost()` | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| `to_location(x, y)` | 滚动条坐标值,左上角为 (0 , 0) | 滚动到指定位置 |
|
||||
| `up(pixel)` | 滚动的像素 | 向上滚动若干像素,水平位置不变 |
|
||||
| `down(pixel)` | 滚动的像素 | 向下滚动若干像素,水平位置不变 |
|
||||
| `right(pixel)` | 滚动的像素 | 向左滚动若干像素,垂直位置不变 |
|
||||
| `left(pixel)` | 滚动的像素 | 向右滚动若干像素,垂直位置不变 |
|
||||
|
||||
```python
|
||||
# 页面滚动到底部
|
||||
page.scroll.to_bottom()
|
||||
|
||||
# 页面滚动到最右边
|
||||
page.scroll.to_rightmost()
|
||||
|
||||
# 页面向下滚动 200 像素
|
||||
page.scroll.down(200)
|
||||
|
||||
# 滚动到指定位置
|
||||
page.scroll.to_location(100, 300)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `scroll_to_see()`
|
||||
|
||||
此方法用于滚动页面直到元素可见。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-------------------------------------:|:---:| ----------------- |
|
||||
| `loc_or_ele` | `str`<br>`tuple`<br>`ChromiumElement` | 必填 | 元素的定位信息,可以是元素、定位符 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 滚动到某个已获取到的元素
|
||||
ele = page.ele('tag:div')
|
||||
page.scroll_to_see(ele)
|
||||
|
||||
# 滚动到按定位符查找到的元素
|
||||
page.scroll_to_see('tag:div')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 处理弹出消息
|
||||
|
||||
## 📍 `handle_alert()`
|
||||
|
||||
此方法 用于处理提示框。
|
||||
它能够设置等待时间,等待提示框出现才进行处理,若超时没等到提示框,返回`None`。
|
||||
也可只获取提示框文本而不处理提示框。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:----------------:|:------:| ------------------------------------------ |
|
||||
| `accept` | `bool`<br>`None` | `True` | `True`表示确认,`False`表示取消,`None`不会按按钮但依然返回文本值 |
|
||||
| `send` | `str` | `None` | 处理 prompt 提示框时可输入文本 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 等待提示框出现的超时时间,为`None`时使用页面整体超时时间 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| --------------- |
|
||||
| `str` | 提示框内容文本 |
|
||||
| `None` | 未等到提示框则返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 确认提示框并获取提示框文本
|
||||
txt = page.handle_alert()
|
||||
|
||||
# 点击取消
|
||||
page.handle_alert(accept=False)
|
||||
|
||||
# 给 prompt 提示框输入文本并点击确定
|
||||
paeg.handle_alert(accept=True, send='some text')
|
||||
|
||||
# 不处理提示框,只获取提示框文本
|
||||
txt = page.handle_alert(accept=None)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 关闭浏览器
|
||||
|
||||
## 📍 `quit()`
|
||||
|
||||
此方法用于关闭浏览器。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`**None`
|
||||
|
||||
```python
|
||||
page.quit()
|
||||
```
|
421
docs/5_ChromiumPage/5_find_elements.md
Normal file
421
docs/5_ChromiumPage/5_find_elements.md
Normal file
@ -0,0 +1,421 @@
|
||||
浏览器页面对象获取元素对象的方式,与`SessionPage`获取元素对象的方法是一致的,但比后者有更多功能。本节重点介绍其独有功能,与`SessionPage`一致的部分,请查看“收发数据包》查找元素”章节。
|
||||
|
||||
# ✔️ 查找元素方法
|
||||
|
||||
## 📍 查找单个元素
|
||||
|
||||
🔸 `ele()`
|
||||
|
||||
页面对象和元素对象都拥有此方法,用于查找第一个匹配条件的元素。
|
||||
|
||||
页面对象和元素对象的`ele()`方法参数名称稍有不同,但用法一样。
|
||||
|
||||
查找元素内置了等待元素出现功能,默认跟随页面设置,也可以每次查找单独调整。
|
||||
|
||||
?>**Tips:**<br>在元素对象的`ele()`方法中使用 xpath 可直接获取后代元素的属性。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------------:|:-----------------------------------------------:|:------:| --------------------------------------------- |
|
||||
| `loc_or_str`(元素对象) | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
| `loc_or_ele`(页面对象) | `str`<br>`ChromiumElement`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串、loc 元组或一个`ChromiumElement`对象 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 查找元素等待时间,为`None`则使用页面对象`timeout`属性值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----------------:| --------------------------------- |
|
||||
| `ChromiumElement` | 返回查找到的第一个符合条件的元素对象 |
|
||||
| `None` | 限时内未找到符合条件的元素时返回`None` |
|
||||
| `str` | 在元素的`ele()`中使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
|
||||
# 在页面内查找元素
|
||||
ele1 = page.ele('#one')
|
||||
|
||||
# 在元素内查找后代元素
|
||||
ele2 = ele1.ele('第二行')
|
||||
|
||||
# 使用 xpath 获取后代中第一个 div 元素的 class 属性(元素内查找可用)
|
||||
ele_class = ele1.ele('xpath://p/@class')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 查找多个元素
|
||||
|
||||
🔸 `eles()`
|
||||
|
||||
此方法与`ele()`相似,但返回的是匹配到的所有元素组成的列表。
|
||||
|
||||
元素对象用 xpath 获取元素属性时,返回属性文本组成的列表。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:------:| ----------------------------------- |
|
||||
| `loc_or_str` | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 查找元素等待时间,为`None`则使用页面对象`timeout`属性值 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----------------------:| ---------------------------------- |
|
||||
| `List[ChromiumElement]` | 返回找到的所有`ChromiumElement`组成的列表 |
|
||||
| `List[str]` | 在元素的`eles()`中使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取ele元素内的所有p元素
|
||||
p_eles = ele.eles('tag:p')
|
||||
# 打印第一个p元素的文本
|
||||
print(p_eles[0].text)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 查找单个静态元素
|
||||
|
||||
静态元素即 s 模式的`SessionElement`
|
||||
元素对象,是纯文本构造的,因此用它处理速度非常快。对于复杂的页面,要在成百上千个元素中采集数据时,转换为静态元素可把速度提升几个数量级。作者曾在采集的时候,用同一套逻辑,仅仅把元素转换为静态,就把一个要 30
|
||||
秒才采集完成的页面,加速到零点几秒完成。
|
||||
我们甚至可以把整个页面转换为静态元素,再在其中提取信息。
|
||||
当然,这种元素不能进行点击等交互。
|
||||
用`s_ele()`可在把查找到的动态元素转换为静态元素输出,或者获取元素或页面本身的静态元素副本。
|
||||
|
||||
🔸 `s_ele()`
|
||||
|
||||
页面对象和元素对象都拥有此方法,用于查找第一个匹配条件的元素,获取其静态版本。
|
||||
|
||||
页面对象和元素对象的`s_ele()`方法参数名称稍有不同,但用法一样。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------------:|:-----------------------------------------------:|:---:| --------------------------------------------- |
|
||||
| `loc_or_str`(元素对象) | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
| `loc_or_ele`(页面对象) | `str`<br>`ChromiumElement`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串、loc 元组或一个`ChromiumElement`对象 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------:| --------------------------------- |
|
||||
| `SessionElement` | 返回查找到的第一个符合条件的元素对象的静态版本 |
|
||||
| `None` | 限时内未找到符合条件的元素时返回`None` |
|
||||
| `str` | 在元素的`ele()`中使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
!>**注意:**<br>页面对象和元素对象的`s_ele()`方法不能搜索到在`<iframe>`里的元素,页面对象的静态版本也不能搜索`<iframe>`里的元素。要使用`<iframe>`
|
||||
里元素的静态版本,可先获取该元素,再转换。而使用`ChromiumFrame`对象,则可以直接用`s_ele()`查找元素,这在后面章节再讲述。
|
||||
|
||||
?>**Tips:**<br>从一个`ChromiumElement`元素获取到的`SessionElement`版本,依然能够使用相对定位方法定位祖先或兄弟元素。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
p = ChromiumPage()
|
||||
|
||||
# 在页面中查找元素,获取其静态版本
|
||||
ele1 = page.s_ele('search text')
|
||||
|
||||
# 在动态元素中查找元素,获取其静态版本
|
||||
ele = page.ele('search text')
|
||||
ele2 = ele.s_ele()
|
||||
|
||||
# 获取页面元素的静态副本(不传入参数)
|
||||
s_page = page.s_ele()
|
||||
|
||||
# 获取动态元素的静态副本
|
||||
s_ele = ele.s_ele()
|
||||
|
||||
# 在静态副本中查询下级元素(因为已经是静态元素,用ele()查找结果也是静态)
|
||||
ele3 = s_page.ele('search text')
|
||||
ele4 = s_ele.ele('search text')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 查找多个静态元素
|
||||
|
||||
查找多个静态元素使用`s_eles()`方法。
|
||||
|
||||
此方法与`s_ele()`相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------:|:---:| ------------------------- |
|
||||
| `loc_or_str` | `str`<br>`Tuple[str, str]` | 必填 | 元素的定位信息,可以是查询字符串,或 loc 元组 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:----------------------:| ---------------------------------- |
|
||||
| `List[SessionElement]` | 返回找到的所有元素的`SessionElement`版本组成的列表 |
|
||||
| `List[str]` | 在元素的`eles()`中使用 xpath,可直接获取后代元素的属性 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
p = WebPage()
|
||||
for ele in p.s_eles('search text'):
|
||||
print(ele.text)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取当前焦点元素
|
||||
|
||||
使用`active_ele`属性获取页面上焦点所在元素。
|
||||
|
||||
```python
|
||||
ele = page.active_ele
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取 shadow_root
|
||||
|
||||
d 模式元素如果包含 shadow_root,可使用`shadow_root`属性获取。
|
||||
该属性返回的是一个`ChromiumShadowRootElement`对象,用法与`ChromiumElement`相似。也能使用各种元素查找方式,返回内部元素或相对位置元素,返回 `ChromiumElement`
|
||||
元素。返回的`ChromiumElement`和普通的没有区别。
|
||||
|
||||
```python
|
||||
# 获取一个元素下是 shadow root
|
||||
shadow_ele = ele.shadow_root
|
||||
# 获取该 shadow root 下的一个元素
|
||||
ele1 = shadow_ele.ele('search text')
|
||||
# 点击获取到的元素
|
||||
ele1.click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 查找语法
|
||||
|
||||
查找语法与`SessionPage`一致,此处只放个汇总表,详情请查看“收发数据包》查找元素”章节。
|
||||
|
||||
| 匹配符 | 说明 | 示例 |
|
||||
|:--------:| ------------------- | --------------------------- |
|
||||
| `=` | 精确匹配符 | `'@name=row1'` |
|
||||
| `:` | 模糊匹配符 | `'@name:row'` |
|
||||
| `#` | id 匹配符 | `'#one'` |
|
||||
| `.` | class 匹配符 | `'.p_cls'` |
|
||||
| `@` | 单属性匹配符 | `'@name=row1'` |
|
||||
| `@@` | 多属性匹配符 | `'@@name:row@@class:p_cls'` |
|
||||
| `text` | 文本匹配符 | `'text=第一行'` |
|
||||
| `text()` | 与`@`或`@@`配合使用的文本匹配符 | `'@text()=第二行'` |
|
||||
| `tag` | 类型匹配符 | `'tag:div'` |
|
||||
| `css` | css selector 匹配符 | `'css:.div'` |
|
||||
| `xpath` | xpath 匹配符 | `'xpath://div'` |
|
||||
| loc 元组 | selenium 的定位元组 | `(By.ID, 'abc')` |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 相对定位
|
||||
|
||||
相对语法与`SessionPage`一致,此处只放个汇总表,详情请查看“收发数据包》查找元素”章节。
|
||||
|
||||
注意有以下两点差异:
|
||||
|
||||
- `timeout`参数是有效的,会等待目标元素出现
|
||||
|
||||
- 返回的类型是`ChromiumElement`而非`SessionElement`
|
||||
|
||||
| 方法 | 说明 |
|
||||
|:-----------:| ------------------------------------------------------------------- |
|
||||
| `parent()` | 此方法获取当前元素某一级父元素,可指定筛选条件或层数 |
|
||||
| `next()` | 此方法返回当前元素后面的某一个同级元素,可指定筛选条件和第几个 |
|
||||
| `nexts()` | 此方法返回当前元素后面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选 |
|
||||
| `prev()` | 此方法返回当前元素前面的某一个同级元素,可指定筛选条件和第几个 |
|
||||
| `prevs()` | 此方法返回当前元素前面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选 |
|
||||
| `after()` | 此方法返回当前元素后面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档 |
|
||||
| `afters()` | 此方法返回当前元素后面符合条件的全部元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档 |
|
||||
| `before()` | 此方法返回当前元素前面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档 |
|
||||
| `befores()` | 此方法返回当前元素前面全部符合条件的元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 等待
|
||||
|
||||
## 📍 等待元素加载
|
||||
|
||||
由于网络、js 运行时间的不确定性等因素,经常须要等待元素加载到 DOM 中才能使用。
|
||||
|
||||
l浏览器所有查找元素操作都自带等待,时间默认跟随元素所在页面`timeout`属性(默认 10 秒),也可以在每次查找时单独设置,单独设置的等待时间不会改变页面原来设置。
|
||||
|
||||
```python
|
||||
# 页面初始化时设置查找元素超时时间为 15 秒
|
||||
page = ChromiumPage(timeout=15)
|
||||
# 设置查找元素超时时间为 5 秒
|
||||
page.timeout = 5
|
||||
|
||||
# 使用页面超时时间来查找元素(5 秒)
|
||||
ele1 = page.ele('search text')
|
||||
# 为这次查找页面独立设置等待时间(1 秒)
|
||||
ele1 = page.ele('search text', timeout=1)
|
||||
# 查找后代元素,使用页面超时时间(5 秒)
|
||||
ele2 = ele1.ele('search text')
|
||||
# 查找后代元素,使用单独设置的超时时间(1 秒)
|
||||
ele2 = ele1.ele('some text', timeout=1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 等待元素状态改变
|
||||
|
||||
有时候我们须要等待元素到达某种状态,如显示、隐藏、删除。页面对象和元素对象都内置了`wait_ele()`方法,用于等待元素状态变化。
|
||||
|
||||
该方法可接收现成的`ChromiumElement`对象,或定位符,再调用内置方法实现等待。
|
||||
|
||||
默认等待时间为页面对象的`timeout`值,也可以单独设定。
|
||||
|
||||
🔸 `wait_ele()`方法
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-----------------------------------------------:|:------:| ----------------- |
|
||||
| `loc_or_ele` | `str`<br>`Tuple[str, str]`<br>`ChromiumElement` | 必填 | 要等待的元素,可以是元素或定位符 |
|
||||
| `timeout` | `int`<br>`float` | `None` | 等待超时时间,默认使用页面超时时间 |
|
||||
|
||||
| 内置方法 | 参数 | 返回 | 功能 |
|
||||
|:-----------:|:---:|:--------------:| ------------ |
|
||||
| `display()` | 无 | `bool`表示是否等待成功 | 等待元素从 DOM 显示 |
|
||||
| `hidden()` | 无 | `bool`表示是否等待成功 | 等待元素从 DOM 隐藏 |
|
||||
| `delete()` | 无 | `bool`表示是否等待成功 | 等待元素从 DOM 删除 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 等待 id 为 div1 的元素显示,超时使用页面设置
|
||||
page.wait_ele('#div1').display()
|
||||
|
||||
# 等待 id 为 div1 的元素被删除(使用 loc 元组),设置超时3秒
|
||||
ele.wait_ele('#div1', timeout=3).delete()
|
||||
|
||||
# 等待已获取到的元素被隐藏
|
||||
ele2 = ele1.ele('#div1')
|
||||
ele1.wait_ele(ele2).hidden()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 查找 iframe 里的元素
|
||||
|
||||
## 📍 在页面下跨级查找
|
||||
|
||||
与 selenium 不同,本库可以直接查找`<iframe>`里面的元素,而且无视层级,可以直接获取到多层`<iframe>`里的元素。无需切入切出,大大简化了程序逻辑,使用更便捷。
|
||||
|
||||
假设在页面中有个两级`<iframe>`,其中有个元素`<div id='abc'></div>`,可以这样获取:
|
||||
|
||||
```python
|
||||
page = ChromiumPage()
|
||||
ele = page('#abc')
|
||||
```
|
||||
|
||||
获取前后无须切入切出,也不影响获取页面上其它元素。
|
||||
|
||||
如果用 selenium,要这样写:
|
||||
|
||||
```python
|
||||
driver = webdriver.Chrome()
|
||||
driver.switch_to.frame(0)
|
||||
driver.switch_to.frame(0)
|
||||
ele = driver.find_element(By.ID, 'abc')
|
||||
driver.switch_to.default_content()
|
||||
```
|
||||
|
||||
显然比较繁琐,而且切入到`<iframe>`后无法对`<iframe>`外的元素进行操作。
|
||||
|
||||
!>**注意:**<br>- 跨级查找只是页面对象支持,元素对象不能直接查找内部 iframe 里的元素。<br>- 跨级查找只能用于与主框架同域名的`<iframe>`,不同域名的请用下面的方法。
|
||||
|
||||
---
|
||||
|
||||
## 📍 在 iframe 元素下查找
|
||||
|
||||
本库把`<iframe>`看作一个特殊元素/页面对象看待,可以实现同时操作多个`<iframe>`,而无须来回切换。
|
||||
|
||||
对于跨域名的`<iframe>`,我们无法通过页面直接查找里面的元素,可以先获取到`<iframe>`元素,再在其下查找。当然,非跨域`<iframe>`也可以这样操作。
|
||||
|
||||
假设一个`<iframe>`的 id 为 `'iframe1'`,要在其中查找一个 id 为`'abc'`的元素:
|
||||
|
||||
```python
|
||||
page = ChromiumPage()
|
||||
iframe = page('#iframe1')
|
||||
ele = iframe('#abc')
|
||||
```
|
||||
|
||||
这个`<iframe>`元素是一个页面对象,因此可以继续在其下进行跨`<iframe>`查找(相对这个`<iframe>`不跨域的)。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `ShadowRootElement`相关查找
|
||||
|
||||
本库把 shadow-root 也作为元素对象看待,是为`ChromiumShadowRootElement`对象。该对象可与普通元素一样查找下级元素和 DOM 内相对定位。
|
||||
对`ChromiumShadowRootElement`对象进行相对定位时,把它看作其父对象内部的第一个对象,其余定位逻辑与普通对象一致。
|
||||
|
||||
!> **注意:** <br>如果`ChromiumShadowRootElement`元素的下级元素中有其它`ChromiumShadowRootElement`元素,那这些下级`ChromiumShadowRootElement`
|
||||
元素内部是无法直接通过定位语句查找到的,只能先定位到其父元素,再用`shadow-root`属性获取。
|
||||
|
||||
```python
|
||||
# 获取一个 shadow-root 元素
|
||||
sr_ele = page.ele('#app').shadow_root
|
||||
|
||||
# 在该元素下查找下级元素
|
||||
ele1 = sr_ele.ele('tag:div')
|
||||
|
||||
# 用相对定位获取其它元素
|
||||
ele1 = sr_ele.parent(2)
|
||||
ele1 = sr_ele.next('tag:div', 1)
|
||||
ele1 = sr_ele.after('tag:div', 1)
|
||||
eles = sr_ele.nexts('tag:div')
|
||||
|
||||
# 定位下级元素中的 shadow+-root 元素
|
||||
sr_ele2 = sr_ele.ele('tag:div').shadow_root
|
||||
```
|
||||
|
||||
由于 shadow-root 不能跨级查找,链式操作非常常见,所以设计了一个简写:`sr`,功能和`shadow_root`一样,都是获取元素内部的`ChromiumShadowRootElement`。
|
||||
|
||||
多级 shadow-root 链式操作示例:
|
||||
|
||||
以下这段代码,可以打印浏览器历史第一页,可见是通过多级 shadow-root 来获取的。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.get('chrome://history/')
|
||||
|
||||
items = page('#history-app').sr('#history').sr.eles('t:history-item')
|
||||
for i in items:
|
||||
print(i.sr('#item-container').text.replace('\n', ''))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 简化写法
|
||||
|
||||
为进一步精简代码,对语法进行了精简
|
||||
|
||||
- 定位语法都有其简化形式。
|
||||
- 页面和元素对象都实现了`__call__()`方法,可直接调用。
|
||||
- 所有查找方法都支持链式操作
|
||||
|
||||
示例:
|
||||
|
||||
```python
|
||||
# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
eles = page('#table_id').eles('t:tr')
|
||||
|
||||
# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
ele2 = ele1('.cls1')('tx=text')
|
||||
|
||||
# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
ele2 = ele1.sr('.cls')
|
||||
|
||||
# 按xpath 查找元素
|
||||
ele2 = ele1('x://div[@class="ele_class"]')
|
||||
```
|
||||
|
||||
简化写法对应列表
|
||||
|
||||
| 原写法 | 简化写法 |
|
||||
|:-------------:|:------:|
|
||||
| `text` | `tx` |
|
||||
| `text()` | `tx()` |
|
||||
| `tag` | `t` |
|
||||
| `xpath` | `x` |
|
||||
| `css` | `c` |
|
||||
| `shadow_root` | `sr` |
|
347
docs/5_ChromiumPage/6_get_element_info.md
Normal file
347
docs/5_ChromiumPage/6_get_element_info.md
Normal file
@ -0,0 +1,347 @@
|
||||
浏览器元素对应的对象是`ChromiumElement`和`ChromiumShadowRootElement`,本节介绍获取到元素对象后,如何获取其信息。
|
||||
|
||||
`ChromiumElement`拥有`SessionElement`所有属性,并有更多浏览器专属的信息。本节重点介绍如何获取浏览器专有的元素信息。
|
||||
|
||||
# ✔️ 与`SessionElement`共有信息
|
||||
|
||||
此处仅列出列表,具体用法请查看收发数据包部分的“获取元素信息”。
|
||||
|
||||
| 属性或方法 | 说明 |
|
||||
|:------------:| -------------------------------- |
|
||||
| `html` | 此属性返回元素的`outerHTML`文本 |
|
||||
| `inner_html` | 此属性返回元素的`innerHTML`文本 |
|
||||
| `tag` | 此属性返回元素的标签名 |
|
||||
| `text` | 此属性返回元素内所有文本组合成的字符串 |
|
||||
| `raw_text` | 此属性返回元素内原始文本 |
|
||||
| `texts()` | 此方法返回元素内所有**直接**子节点的文本,包括元素和文本节点 |
|
||||
| `comments` | 此属性以列表形式返回元素内的注释 |
|
||||
| `attrs` | 此属性以字典形式返回元素所有属性及值 |
|
||||
| `attr()` | 此方法返回元素某个`attribute`属性值 |
|
||||
| `link` | 此方法返回元素的 href 属性或 src 属性 |
|
||||
| `page` | 此属性返回元素所在的页面对象 |
|
||||
| `xpath` | 此属性返回当前元素在页面中 xpath 的绝对路径 |
|
||||
| `css_path` | 此属性返回当前元素在页面中 css selector 的绝对路径 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 获取大小和位置
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以元组形式返回元素的大小。
|
||||
|
||||
```python
|
||||
size = ele.size
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `location`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以元组形式返回元素**左上角**在**整个页面**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.location
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `client_location`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以元组形式返回元素**左上角**在**当前视口**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.client_location
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `midpoint`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以元组形式返回元素**中点**在**整个页面**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.midpoint
|
||||
# 返回:(55, 55)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `client_midpoint`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以元组形式返回元素**中点**在**视口**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.client_midpoint
|
||||
# 返回:(55, 55)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 获取属性和内容
|
||||
|
||||
## 📍 `pseudo_before`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性以文本形式返回当前元素的`::before`伪元素内容。
|
||||
|
||||
```python
|
||||
before_txt = ele.pseudo_before
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `pseudo_after`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性以文本形式返回当前元素的`::after`伪元素内容。
|
||||
|
||||
```python
|
||||
after_txt = ele.pseudo_after
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `style()`
|
||||
|
||||
该方法返回元素 css 样式属性值,可获取伪元素的属性。它有两个参数,`style`参数输入样式属性名称,`pseudo_ele`参数输入伪元素名称,省略则获取普通元素的 css 样式属性。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:-----:|:----:| --------- |
|
||||
| `style` | `str` | 必填 | 样式名称 |
|
||||
| `pseudo_ele` | `str` | `''` | 伪元素名称(如有) |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----:| ----- |
|
||||
| `str` | 样式属性值 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 获取 css 属性的 color 值
|
||||
prop = ele.style('color')
|
||||
|
||||
# 获取 after 伪元素的内容
|
||||
prop = ele.style('content', 'after')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `prop()`
|
||||
|
||||
此方法返回`property`属性值。它接收一个字符串参数,返回该参数的属性值。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| ---- |
|
||||
| `prop` | `str` | 必填 | 属性名称 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-----:| --- |
|
||||
| `str` | 属性值 |
|
||||
|
||||
---
|
||||
|
||||
## 📍 `shadow_root`
|
||||
|
||||
**类型:**`ChromiumShadowRootElement`
|
||||
|
||||
此属性返回元素内的 shadow-root 对象,没有的返回`None`。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 获取状态信息
|
||||
|
||||
## 📍`is_in_viewport`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性以布尔值方式返回元素是否在视口中,以元素可以接受点击的点为判断。
|
||||
|
||||
---
|
||||
|
||||
## 📍`is_alive`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性以布尔值形式返回当前元素是否仍可用。用于判断 d 模式下是否因页面刷新而导致元素失效。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_selected`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性以布尔值返回元素是否选中。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_enabled`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性以布尔值返回元素是否可用。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_displayed`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性以布尔值返回元素是否可见。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 保存和截图
|
||||
|
||||
保存功能是本库一个特色功能,可以直接读取浏览器缓存,无须依赖另外的 ui 库或重新下载就可以保存页面资源。
|
||||
|
||||
作为对比,selenium 无法自身实现图片另存,往往须要通过使用 ui 工具进行辅助,不仅效率和可靠性低,还占用键鼠资源。
|
||||
|
||||
## 📍 `get_src()`
|
||||
|
||||
此方法用于返回元素`src`属性所使用的资源。base64 的会转为`bytes`返回,其它的以`str`返回。无资源的返回`None`。
|
||||
|
||||
例如,可获取页面上图片字节数据,用于识别内容,或保存到文件。`<script>`标签也可获取 js 文本。
|
||||
|
||||
!> **注意:**<br>无法获取 Blob 内容。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------ |
|
||||
| `str` | 资源字符串 |
|
||||
| `None` | 无资源的返回`None` |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
src = img.get_src()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `save()`
|
||||
|
||||
此方法用于保存`get_src()`方法获取到的资源到文件。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:-------------------------:|:------:| ----------------------------- |
|
||||
| `path` | `str`<br>`Path`<br>`None` | `None` | 文件保存路径,为`None`时保存到当前文件夹 |
|
||||
| `rename` | `str`<br>`None` | `None` | 文件名称,须包含后缀,为`None`时从资源 url 获取 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
img.save('D:\\img.png')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get_screenshot()`
|
||||
|
||||
此方法用于对元素进行截图。若截图时元素在视口外,须 90 以上版本内核支持。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `path`:图片完整路径,后缀可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`
|
||||
|
||||
- `as_bytes`:是否已字节形式返回图片,可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`。为`True`时以`'png'`输出。生效时`path`参数无效。
|
||||
|
||||
**返回:** 图片完整路径或字节文本
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:-------------------------:|:------:| --------------------------------------------------------------------------------------------------------- |
|
||||
| `path` | `str`<br>`Path`<br>`None` | `None` | 保存图片的完整路径,文件后缀可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`<br>为`None`时以 jpg 格式保存在当前文件夹 |
|
||||
| `as_bytes` | `str`<br>`None`<br>`True` | `None` | 是否已字节形式返回图片,可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`、`None`、`True`<br>不为`None`时`path`参数无效<br>为`True`时选用 jpg 格式 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-------:| -------------------------- |
|
||||
| `bytes` | `as_bytes`生效时返回图片字节 |
|
||||
| `str` | `as_bytes`为`None`时返回图片完整路径 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
img.get_screenshot()
|
||||
bytes_str = img.get_screenshot(as_bytes='png') # 返回截图二进制文本
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `ChromiumShadowRootElement`属性
|
||||
|
||||
本库把 shadow dom 的`root`看作一个元素处理,可以获取属性,也可以执行其下级的查找,使用逻辑与`ChromiumElement`一致,但属性较之少,有如下这些:
|
||||
|
||||
## 📍 `tag`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回元素标签名,即`'shadow-root'`。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回`shadow_root`的 html 文本,由`<shadow_root></shadow_root>` 标签包裹。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `inner_html`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回`shadow_root`内部的 html 文本。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `page`
|
||||
|
||||
**类型:**`ChromiumPage`、`ChromiumTab`、`ChromiumFrame`、`WebPage`
|
||||
|
||||
此属性返回元素所在页面对象。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `parent_ele`
|
||||
|
||||
**类型:**`ChromiumElement`
|
||||
|
||||
此属性返回所依附的普通元素对象。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_enabled`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
与`ChromiumElement`一致。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_alive`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
与`ChromiumElement`一致。
|
@ -1,57 +1,59 @@
|
||||
只有 d 模式下才能对元素进行操作,本节介绍普通元素`ChromiumElement`内置方法。
|
||||
|
||||
iframe 元素`ChromiumFrame`使用方法后面章节单独介绍。
|
||||
本节介绍与浏览器元素的交互。浏览器元素对象为`ChromiumElement`。
|
||||
|
||||
# ✔️ 点击元素
|
||||
|
||||
## 📍 `click()`
|
||||
|
||||
此方法用于点击元素。可选择模拟点击或 js 点击。
|
||||
此方法用于点击元素。可选择模拟点击或 js 点击。并支持点击重试功能。
|
||||
|
||||
还可以在点击被遮挡时执行重试。`retry`参数为`True`、`by_js`参数为`None`时,会先用模拟方式点击,若遇到其它元素遮挡,会重试点击直到超时。若都失败,自动改用 js 方式进行点击。
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------------:|:--------------------------:|:-------:| ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `by_js` | `bool` | `None` | 是否用 js 方式点击<br>为`True`时直接用 js 点击,不重试;<br>为`False`时只用模拟点击,且根据`retry`设置重试;<br>为`None`时先用模拟点击并根据`retyr`设置重试,如全部失败,改用 js 点击 |
|
||||
| `retry` | `bool` | `False` | 遇到其它元素遮挡时,是否重试 |
|
||||
| `timeout` | `int`<br>`float` | `0.2` | 点击失败重试超时时间,为`None`时使用父页面`timeout`设置,`retry`为`True`时才生效 |
|
||||
| `wait_loading` | `int`<br>`float`<br>`True` | `0` | 指定等待页面进入加载状态的超时时间,为`True`时等待 2 秒,默认 0 秒 |
|
||||
|
||||
`by_js`参数为`True`时,只会通过 js 点击一次,不会重试。
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------ |
|
||||
| `bool` | 是否点击成功 |
|
||||
|
||||
此设计除了可保证点击成功,还可以用于检测页面上的遮罩层是否消失。遮罩层经常出现在 js 方式翻页的时候,它的覆盖会阻碍模拟点击,所以可以通过对其下面的元素不断重试点击,来判断遮罩层是否存在。当然,这个方法是否可行要看具体网页设计。
|
||||
点击重试的设计,可以用于检测页面上的遮罩层是否消失。遮罩层经常出现在 js 方式翻页的时候,它的覆盖会阻碍模拟点击,所以可以通过对其下面的元素不断重试点击,来判断遮罩层是否存在。
|
||||
而如果直接使用 js 进行点击,则可无视任何遮挡,只要元素在 DOM 内,就能点击得到,这样可以根据须要灵活地对元素进行操作。
|
||||
|
||||
通常,点击链接后立刻获取新页面的元素,程序可自动等待元素加载,但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。可以把`wait_loading`参数设置一个超时时间,点击后程序会等待页面进入 loading 状态,才会继续往下执行,从而避免上述问题。
|
||||
通常,点击链接后立刻获取新页面的元素,程序可自动等待元素加载,但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。可以对`wait_loading`参数设置一个超时时间,点击后程序会等待页面进入
|
||||
loading 状态,才会继续往下执行,从而避免上述问题。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `by_js`:是否用 js 方式点击,为`None`时如`retry`为`True`,先用模拟方法点击,重试失败超时后改为用 js 点击;为`True`时直接用 js 点击;为`False`时即使重试超时也不会改用 js
|
||||
- `retry`:遇到其它元素遮挡时,是否重试
|
||||
- `timeout`:点击失败重试超时时间,为`None`时使用父页面`timeout`设置
|
||||
- `wait_loading`:等待页面进入加载状态的超时时间,默认 0
|
||||
|
||||
**返回:**`bool`,表示是否点击成功。
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 对 ele 元素进行点击
|
||||
# 对ele元素进行点击
|
||||
ele.click()
|
||||
|
||||
# 用 js 方式点击 ele 元素
|
||||
# 用js方式点击ele元素
|
||||
ele.click(by_js=True)
|
||||
|
||||
# 假设遮罩层出现,ele 是遮罩层下方的元素
|
||||
# 假设遮罩层出现,ele是遮罩层下方的元素
|
||||
ele.click(by_js=False, retry=True, timeout = 10) # 不断重试点击,直到遮罩层消失,或到达 10 秒
|
||||
ele.click(by_js=True) # 无视遮罩层,直接用 js 点击下方元素
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `click_at()`
|
||||
|
||||
此方法用于带偏移量点击元素,偏移量相对于元素左上角坐标。不传入`offset_x`或`offset_y`值时点击元素中上部可接受点击的点。
|
||||
可用于点击一些奇怪的东西,比如用伪元素表示的控件。
|
||||
此方法用于带偏移量点击元素,偏移量相对于元素左上角坐标。不传入`offset_x`和`offset_y`时点击元素中上部位置。
|
||||
点击的目标不一定在元素上,可以传入负值,或大于元素大小的值,点击元素附近的区域。向右和向下为正值,向左和向上为负值。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `offset_x`:相对元素左上角坐标的 x 轴偏移量
|
||||
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
|
||||
- `button`:点击哪个键,传入`'left'`、`'right'`或`'middle'`
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:-----:|:--------:| ------------------------------------- |
|
||||
| `offset_x` | `int` | `None` | 相对元素左上角坐标的 x 轴偏移量,向下向右为正 |
|
||||
| `offset_y` | `int` | `None` | 相对元素左上角坐标的 y 轴偏移量,向下向右为正 |
|
||||
| `button` | `str` | `'left'` | 要点击的键,传入`'left'`、`'right'`或`'middle'` |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 点击元素右上方 50*50 的位置
|
||||
ele.click_at(50, -50)
|
||||
@ -63,6 +65,8 @@ ele.click_at(offset_x=50)
|
||||
ele.click_at()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `r_click()`
|
||||
|
||||
此方法实现右键单击元素。
|
||||
@ -71,26 +75,34 @@ ele.click_at()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.r_click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `r_click_at()`
|
||||
|
||||
此方法用于带偏移量右键点击元素,用法和`click_at()`相似。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `offset_x`:相对元素左上角坐标的 x 轴偏移量
|
||||
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:-----:|:------:| ------------------------ |
|
||||
| `offset_x` | `int` | `None` | 相对元素左上角坐标的 x 轴偏移量,向下向右为正 |
|
||||
| `offset_y` | `int` | `None` | 相对元素左上角坐标的 y 轴偏移量,向下向右为正 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 点击距离元素左上角 50*50 的位置(位于元素内部)
|
||||
ele.r_click_at(50, 50)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `m_click()`
|
||||
|
||||
此方法实现中键单击元素。
|
||||
@ -99,10 +111,14 @@ ele.r_click_at(50, 50)
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.m_click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 输入内容
|
||||
|
||||
## 📍 `clear()`
|
||||
@ -111,32 +127,35 @@ ele.m_click()
|
||||
|
||||
模拟按键方式会自动输入`ctrl-a-del`组合键来清除文本框,js 方式则直接把元素`value`属性设置为`''`。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `by_js`:是否用 js 方式清空
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:------:|:-------:| ----------- |
|
||||
| `by_js` | `bool` | `False` | 是否用 js 方式清空 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.clear()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `input()`
|
||||
|
||||
此方法用于向元素输入文本或组合键,也可用于输入文件路径到`input`元素。可选择输入前是否清空元素。
|
||||
此方法用于向元素输入文本或组合键,也可用于输入文件路径到上传控件。可选择输入前是否清空元素。
|
||||
|
||||
组合键以`tuple`方式传入。
|
||||
|
||||
多行上传控件,多个路径以`list`、`tuple`或以`\n`分隔的字符串传入。
|
||||
?> **Tips:** <br>- 有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上`'\n'`。<br>- 会自动把非`str`数据转换为`str`。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `vals`:文本值或按键组合,
|
||||
- `clear`:输入前是否清空文本框
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:------:|:-------:| ---------------------------------- |
|
||||
| `vals` | `Any` | `False` | 文本值或按键组合<br>对文件上传控件时输入路径字符串或其组成的列表 |
|
||||
| `clear` | `bool` | `True` | 输入前是否清空文本框 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
?>**Tips:** <br>- 有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上`'\n'`。<br>- 会自动把非`str`数据转换为`str`。
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 输入文本
|
||||
ele.input('Hello world!')
|
||||
@ -145,22 +164,24 @@ ele.input('Hello world!')
|
||||
ele.input('Hello world!\n')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 输入组合键
|
||||
|
||||
使用组合键或要传入特殊按键前,先要导入按键类`Keys`。
|
||||
|
||||
```python
|
||||
from DrissionPage.keys import Keys
|
||||
from DrissionPage import Keys
|
||||
```
|
||||
|
||||
然后将组合键放在一个`tuple`中传入`input()`即可。
|
||||
|
||||
```python
|
||||
from DrissionPage.keys import Keys
|
||||
|
||||
ele.input((Keys.CTRL, 'a', Keys.DEL)) # ctrl+a+del
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 上传文件
|
||||
|
||||
上传文件是用`input()`对`type`属性为`'file'`的`<input>`元素进行输入,把文件路径输入到元素即可,用法与输入文本一致。
|
||||
@ -182,40 +203,48 @@ paths = ['D:\\test1.txt', 'D:\\test2.txt']
|
||||
ele.input(paths)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 拖拽和悬停
|
||||
|
||||
?> 除了以下方法,本库还提供更灵活的动作链`ActionChains`功能,详见后面章节。
|
||||
?>**Tips:** <br>除了以下方法,本库还提供更灵活的动作链`ActionChains`功能,详见后面章节。
|
||||
|
||||
## 📍 `drag()`
|
||||
|
||||
此方法用于拖拽元素到相对于当前的一个新位置,可以设置速度,可以选择是否随机抖动。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `offset_x`:x 变化值
|
||||
- `offset_y`:y 变化值
|
||||
- `speed`:拖动的速度,传入 0 即瞬间到达
|
||||
- `shake`:是否随机抖动
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:------:|:------:| ---------------- |
|
||||
| `offset_x` | `int` | `0` | x 轴偏移量,向下向右为正 |
|
||||
| `offset_y` | `int` | `0` | y 轴偏移量,向下向右为正 |
|
||||
| `speed` | `int` | `40` | 拖动的速度,传入 0 即瞬间到达 |
|
||||
| `shake` | `bool` | `True` | 是否随机抖动 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 拖动当前元素到距离 50*50 的位置,速度为 100,不随机抖动
|
||||
ele.drag(50, 50, 100, False)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `drag_to()`
|
||||
|
||||
此方法用于拖拽元素到另一个元素上或一个坐标上。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `ele_or_loc`: 另一个元素对象或坐标元组
|
||||
- `speed`: 拖动的速度,传入 0 即瞬间到达
|
||||
- `shake`: 是否随机抖动
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:--------------------------------------:|:------:| ---------------- |
|
||||
| `ele_or_loc` | `ChromiumElement`<br>`Tuple[int, int]` | 必填 | 另一个元素对象或坐标元组 |
|
||||
| `speed` | `int` | `40` | 拖动的速度,传入 0 即瞬间到达 |
|
||||
| `shake` | `bool` | `True` | 是否随机抖动 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 把 ele1 拖拽到 ele2 上
|
||||
ele1 = page.ele('#div1')
|
||||
@ -226,17 +255,21 @@ ele1.drag_to(ele2)
|
||||
ele1.drag_to((50, 50))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `hover()`
|
||||
|
||||
此方法用于模拟鼠标悬停在元素上,可接受偏移量,偏移量相对于元素左上角坐标。不传入`offset_x`或`offset_y`值时悬停在元素中点。
|
||||
此方法用于模拟鼠标悬停在元素上,可接受偏移量,偏移量相对于元素左上角坐标。不传入`offset_x`和`offset_y`值时悬停在元素中点。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `offset_x`:相对元素左上角坐标的 x 轴偏移量
|
||||
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:-----:|:------:| ------------------------ |
|
||||
| `offset_x` | `int` | `None` | 相对元素左上角坐标的 x 轴偏移量,向下向右为正 |
|
||||
| `offset_y` | `int` | `None` | 相对元素左上角坐标的 y 轴偏移量,向下向右为正 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 悬停在元素右上方 50*50 的位置
|
||||
ele.hover(50, -50)
|
||||
@ -248,78 +281,98 @@ ele.hover(offset_x=50)
|
||||
ele.hover()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 修改元素
|
||||
|
||||
## 📍 `set_innerHTML()`
|
||||
|
||||
此方法用于设置元素的 innerHTML内容。
|
||||
此方法用于设置元素的 innerHTML 内容。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `html`:html文本
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| ------ |
|
||||
| `html` | `str` | 必填 | html文本 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_prop()`
|
||||
|
||||
此方法用于设置元素`property`属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `prop`: 属性名
|
||||
- `value`: 属性值
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| --- |
|
||||
| `prop` | `str` | 必填 | 属性名 |
|
||||
| `value` | `str` | 必填 | 属性值 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.set_prop('value', 'Hello world!')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_attr()`
|
||||
|
||||
此方法用于设置元素`attribute`属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
- `value`:属性值
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| --- |
|
||||
| `attr` | `str` | 必填 | 属性名 |
|
||||
| `value` | `str` | 必填 | 属性值 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.set_attr('href', 'http://www.gitee.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `remove_attr()`
|
||||
|
||||
此方法用于删除元素`attribute`属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| --- |
|
||||
| `attr` | `str` | 必填 | 属性名 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.remove_attr('href')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 执行 js 脚本
|
||||
|
||||
## 📍 `run_js()`
|
||||
|
||||
此方法用于对元素执行 js 代码,代码中用`this`表示元素自己。
|
||||
|
||||
**参数:**
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| ----------------------------------------------- |
|
||||
| `script` | `str` | 必填 | js 脚本文本 |
|
||||
| `as_expr` | `bool` | `False` | 是否作为表达式运行,为`True`时`args`参数无效 |
|
||||
| `*args` | - | 无 | 传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`... |
|
||||
|
||||
- `script`:js 脚本文本
|
||||
- `as_expr`:是否作为表达式运行,为`True`时`args`参数无效
|
||||
- `*args`:传入 js 的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`...
|
||||
|
||||
**返回:** js 执行的结果
|
||||
| 返回类型 | 说明 |
|
||||
|:-----:| ------ |
|
||||
| `Any` | 脚本执行结果 |
|
||||
|
||||
!>**注意:**<br>要获取 js 结果记得写上`return`。
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 用执行 js 的方式点击元素
|
||||
ele.run_js('this.click();')
|
||||
@ -328,12 +381,22 @@ ele.run_js('this.click();')
|
||||
height = ele.run_js('return this.offsetHeight;')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `run_async_script()`
|
||||
|
||||
此方法用于以异步方式执行 js 代码,代码中用`this`表示元素自己。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| ----------------------------------------------- |
|
||||
| `script` | `str` | 必填 | js 脚本文本 |
|
||||
| `as_expr` | `bool` | `False` | 是否作为表达式运行,为`True`时`args`参数无效 |
|
||||
| `*args` | - | 无 | 传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`... |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 元素滚动
|
||||
|
||||
## 📍 `scroll`
|
||||
@ -368,6 +431,8 @@ ele.scroll.down(200)
|
||||
ele.scroll.to_location(100, 300)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 列表选择
|
||||
|
||||
## 📍 `select`
|
||||
@ -394,7 +459,9 @@ ele = page.ele('#s')
|
||||
ele.select('text1') # 选中文本为 'text1' 的项目
|
||||
```
|
||||
|
||||
## 📍 方法
|
||||
---
|
||||
|
||||
## 📍 对象方法
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:---------------------------------:|:-------:|:--------------:|
|
||||
@ -407,6 +474,8 @@ ele.select('text1') # 选中文本为 'text1' 的项目
|
||||
| `invert()` | 无 | 反选(多选列表) |
|
||||
| `clear()` | 无 | 清空列表(多选列表) |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
ele.select.by_text('text1') # 和 ele.select('text1') 一样
|
||||
ele.select.by_value('value2') # 选中 value 属性为 'value2' 的项
|
||||
@ -420,14 +489,30 @@ ele.invert() # 反选
|
||||
ele.clear() # 清空
|
||||
```
|
||||
|
||||
## 📍 属性
|
||||
---
|
||||
|
||||
| 属性 | 说明 |
|
||||
| ------------------ | --------------------- |
|
||||
| `is_multi` | 返回是否多选表单 |
|
||||
| `options` | 返回所有选项元素组成的列表 |
|
||||
| `selected_option` | 返回第一个被选中的option元素 |
|
||||
| `selected_options` | 返回所有被选中的option元素组成的列表 |
|
||||
## 📍 `ChromiumSelect`对象属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:------------------:|:-----------------------:| ------------------------- |
|
||||
| `is_multi` | `bool` | 返回是否多选表单 |
|
||||
| `options` | `List[ChromiumElement]` | 返回所有选项元素组成的列表 |
|
||||
| `selected_option` | `ChromiumElement` | 返回第一个被选中的`<option>`元素 |
|
||||
| `selected_options` | `List[ChromiumElement]` | 返回所有被选中的`<option>`元素组成的列表 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
print(ele.select.is_multi)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
True
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 多选
|
||||
|
||||
@ -446,6 +531,8 @@ ele.select.by_value(('value1', 'value2'))
|
||||
ele.select.cancel_by_index((0, 2))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 等待
|
||||
|
||||
很多网站下拉列表采用 js 加载,如果加载不及时会导致异常。
|
||||
@ -454,8 +541,11 @@ ele.select.cancel_by_index((0, 2))
|
||||
|
||||
```python
|
||||
# 目标选择 'abc',设置超时时间为 3 秒
|
||||
result = ele.select('abc', 3)
|
||||
print(ele.select('abc', 3))
|
||||
```
|
||||
|
||||
# 输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
False
|
||||
```
|
314
docs/5_ChromiumPage/8_tab_operation.md
Normal file
314
docs/5_ChromiumPage/8_tab_operation.md
Normal file
@ -0,0 +1,314 @@
|
||||
本节介绍对浏览器标签页的管理及使用技巧。
|
||||
|
||||
与 selenium 不同,DrissionPage 能够用多个标签页对象同时操作多个标签页,而无须切入切出。并且,标签页无须在激活状态也可以控制。因此能够实现一些非常灵活的使用方式。
|
||||
|
||||
比如,多线程分别独立控制标签页,或一个总标签页,控制多个从标签页,或者配合插件实现浏览器随时更换代理等。
|
||||
|
||||
`ChromiumPage`和`WebPage`对象为浏览器标签页总管,可以控制标签页的增删。`ChromiumTab`对象为独立的标签页对象,可控制每个标签页内的操作。
|
||||
|
||||
# ✔️ 标签页总览
|
||||
|
||||
## 📍 `tabs_count`
|
||||
|
||||
**类型:**`int`
|
||||
|
||||
此属性返回标签页数量。
|
||||
|
||||
```python
|
||||
print(page.tabs_count)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `tabs`
|
||||
|
||||
**类型:**`List[str]`
|
||||
|
||||
此属性以`list`方式返回所有标签页 id。
|
||||
|
||||
```python
|
||||
print(page.tabs)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
['0B300BEA6F1F1F4D5DE406872B79B1AD', 'B838E91F38121B32940B47E8AC59D015']
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 新建标签页
|
||||
|
||||
## 📍 `new_tab()`
|
||||
|
||||
该方法用于新建一个标签页,该标签页在最后面。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----------:|:---------------:|:------:| -------------------- |
|
||||
| `url` | `str`<br>`None` | `None` | 新标签页访问的网址,不传入则新建空标签页 |
|
||||
| `switch_to` | `bool` | `True` | 新建标签页后是否把焦点移过去 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.new_tab(url='https://www.baidu.com')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 关闭标签页
|
||||
|
||||
## 📍 `close_tabs()`
|
||||
|
||||
此方法用于关闭指定的标签页,可关闭多个。默认关闭当前的。
|
||||
|
||||
如果被关闭的标签页包含当前页,会切换到剩下的第一个页面,但未必是视觉上第一个。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:----------------------------------------------:|:------:| ---------------------------------------- |
|
||||
| `tab_ids` | `str`<br>`None`<br>`List[str]`<br>`Tuple[str]` | `None` | 要处理的标签页 id,可传入 id 组成的列表或元组,为`None`时处理当前页 |
|
||||
| `others` | `bool` | `True` | 是否关闭指定标签页之外的 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 关闭当前标签页
|
||||
page.close_tabs()
|
||||
|
||||
# 关闭第1、3个标签页
|
||||
tabs = page.tabs
|
||||
page.close_tabs(tab_ids=(tabs[0], tabs[2]))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `close_other_tabs()`
|
||||
|
||||
此方法用于关闭传入的标签页以外标签页,默认保留当前页。可传入多个。
|
||||
|
||||
如果被关闭的标签页包含当前页,会切换到剩下的第一个页面,但未必是视觉上第一个。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:----------------------------------------------:|:------:| ---------------------------------------- |
|
||||
| `tab_ids` | `str`<br>`None`<br>`List[str]`<br>`Tuple[str]` | `None` | 要处理的标签页 id,可传入 id 组成的列表或元组,为`None`时处理当前页 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 关闭除当前标签页外的所有标签页
|
||||
page.close_other_tabs()
|
||||
|
||||
# 关闭除第一个以外的标签页
|
||||
page.close_other_tabs(page.tab[0])
|
||||
|
||||
# 关闭除指定id以外的标签页
|
||||
reserve_list = ('0B300BEA6F...', 'B838E91...')
|
||||
page.close_other_tabs(reserve_list)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 切换标签页
|
||||
|
||||
## 📍 `main_tab`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
日常使用时,经常会用一个标签页作为主标签页,产生众多临时标签页去进行操作。因此我们可以为每个`ChromiumPage`或`WebPage`对象设置一个标签页为主标签页,方便随时切换。
|
||||
|
||||
默认接管浏览器时活动标签页则为主标签页。
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
print(page.main_tab)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
'0B300BEA6F1F1F4D5DE406872B79B1AD'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `lastest_tab`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回最新的标签页。最新的标签页是指最新出现或最新被激活的标签页。
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 打开了一个标签页
|
||||
ele.click()
|
||||
# 切换到最新打开的标签页
|
||||
page.to_tab(page.lastest_tab)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `set_main_tab()`
|
||||
|
||||
此方法用于设置某个标签页为主标签页。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:---------------:|:------:| ---------------------- |
|
||||
| `tab_id` | `str`<br>`None` | `None` | 要设置的标签页 id,默认设置当前标签页为主 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 指定一个标签页为主标签页
|
||||
page.set_main_tab(tab_id='0B300BEA6F1F1F4D5DE406872B79B1AD')
|
||||
|
||||
# 设置当前控制的标签页为主标签页
|
||||
page.set_main_tab()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍`to_main_tab()`
|
||||
|
||||
此方法用于把焦点定位到主标签页,使当前对象控制目标改为主标签页。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
page.to_main_tab()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `to_tab()`
|
||||
|
||||
此方法把焦点定位到某个标签页,使当前对象控制目标改为该标签页。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:---------------:|:------:| ----------------------- |
|
||||
| `tab_id` | `str`<br>`None` | `None` | 标签页 id,默认为`None`切换到主标签页 |
|
||||
| `activate` | `bool` | `True` | 切换后是否变为活动状态 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
# 切换到主标签页
|
||||
page.to_tab()
|
||||
|
||||
# 切换到第一个标签页
|
||||
page.to_tab(page.tabs[0])
|
||||
|
||||
# 切换到id为该字符串的标签页
|
||||
page.to_tab('0B300BEA6F1F1F4D5DE406872B79B1AD')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `to_front()`
|
||||
|
||||
此方法用于激活当前标签页使其处于最前面。标签页无须在活动状态程序也能操控。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 多标签页协同
|
||||
|
||||
## 📍 获取标签页对象
|
||||
|
||||
可以用`WebPage`或`ChromiumPage`的`get_tab()`方法获取标签页对象,然后可以使用这个对象对标签页进行操作。
|
||||
|
||||
🔸 `get_tab()`
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------:|:---------------:|:------:| --------------------------- |
|
||||
| `tab_id` | `str`<br>`None` | `None` | 要获取的标签页 id,默认为`None`获取当前标签页 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:-------------:| ----- |
|
||||
| `ChromiumTab` | 标签页对象 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
tab = page.get_tab() # 获取当前标签页对象
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 使用标签页对象
|
||||
|
||||
每个`ChromiumTab`对象控制一个浏览器标签页,方法和直接使用`ChromiumPage`一致,只比`ChromiumPage`少了控制标签页功能。
|
||||
|
||||
```python
|
||||
tab.get('https://www.baidu.com') # 使用标签页对象
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 控制多标签页协作示例
|
||||
|
||||
做自动化的时候,我们经常会遇到这样一种场景:我们有一个列表页,须要逐个点开里面的链接,获取新页面的内容,每个链接会打开一个新页面。
|
||||
|
||||
如果用 selenium 来做,点击一个链接后必须把焦点切换到新标签页,采集信息后再回到原来的页面,点击下一个链接,但由于焦点的切换,原来的元素信息已丢失,我们只能重新获取所有链接,以计数方式点击下一个,非常不优雅。
|
||||
|
||||
而用`ChromiumPage`,点开标签页后焦点无须移动,可直接生成一个新标签页的页面对象,对新页面进行采集,而原来列表页的对象可以继续操作下一个链接。甚至可以用多线程控制多个标签页,实现各种黑科技。
|
||||
|
||||
我们用 gitee 的推进项目页面做个演示:[最新推荐项目 - Gitee.com](https://gitee.com/explore/all)
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.get('https://gitee.com/explore/all')
|
||||
|
||||
links = page.eles('t:h3')
|
||||
for link in links[:-1]:
|
||||
# 点击链接
|
||||
link.click()
|
||||
# 获取新标签页对象
|
||||
new_tab = page.get_tab(page.latest_tab)
|
||||
# 等待新标签页加载
|
||||
new_tab.wait_loading()
|
||||
# 打印标签页标题
|
||||
print(new_tab.title)
|
||||
# 关闭除列表页外所有标签页
|
||||
page.close_other_tabs()
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
wx-calendar: 原生小程序日历组件(可滑动,可标记,可禁用)
|
||||
thingspanel-go: 开源插件化物联网平台,Go语言开发。支持MQTT、Modbus多协议、多类型设备接入与可视化、自动化、告警、规则引擎等功能。 QQ群:371794256。
|
||||
APITable: vika.cn维格表社区版,地表至强的开源低代码、多维表格工具,Airtable的开源免费替代。
|
||||
ideaseg: 基于 NLP 技术实现的中文分词插件,准确度比常用的分词器高太多,同时提供 ElasticSearch 和 OpenSearch 插件。
|
||||
vue-plugin-hiprint: hiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑
|
||||
ExDUIR.NET: Windows平台轻量DirectUI框架
|
||||
|
||||
后面省略。。。
|
||||
```
|
@ -24,7 +24,10 @@
|
||||
</html>
|
||||
```
|
||||
|
||||
按`F12`,可以看到网页右侧是一个两层`<iframe>`,一个 id 是`'iframeResult'`的`<iframe>`里面有一个 id 是`'sss'`的`<iframe>`。最里层的`<iframe>`页面指向 https://www.runoob.com。
|
||||
按`F12`,可以看到网页右侧是一个两层`<iframe>`,一个 id 是`'iframeResult'`的`<iframe>`里面有一个 id 是`'sss'`的`<iframe>`。最里层的`<iframe>`
|
||||
页面指向 https://www.runoob.com。
|
||||
|
||||
---
|
||||
|
||||
# ✔ 获取`<iframe>`对象
|
||||
|
||||
@ -35,7 +38,7 @@ iframe = page('#sss')
|
||||
print(iframe.html)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
<iframe id="sss" src="https://www.runoob.com"><html><head>
|
||||
@ -50,6 +53,8 @@ print(iframe.html)
|
||||
|
||||
这个`ChromiumFrame`对象既是页面也是元素,下面演示其功能。
|
||||
|
||||
---
|
||||
|
||||
# ✔ 查找`<iframe>`内元素
|
||||
|
||||
从刚才获取元素对象看出,我们并不须要先切入 id 为`'iframeResult'`的`<iframe>`,就可以获取到里面的元素。所以我们获取元素也并不一定要先获取到`ChromiumFrame`对象。
|
||||
@ -61,10 +66,16 @@ print(iframe.html)
|
||||
```python
|
||||
ele = iframe('首页')
|
||||
print(ele)
|
||||
|
||||
# 输出:<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 页面跨`<iframe>`查找
|
||||
|
||||
如果`<iframe>`元素的网址和主页面是同域的,我们可以直接用页面对象查找`<iframe>`内部元素,而无需先获取`ChromiumFrame`对象:
|
||||
@ -72,12 +83,18 @@ print(ele)
|
||||
```python
|
||||
ele = page('首页')
|
||||
print(ele)
|
||||
```
|
||||
|
||||
# 输出:<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
```
|
||||
|
||||
只要是同域名的,无论跨多少曾`<iframe>`都能用页面对象直接获取。
|
||||
|
||||
---
|
||||
|
||||
## 📍 与 selenium 对比
|
||||
|
||||
`WebPage`:
|
||||
@ -103,80 +120,138 @@ page.to_frame.main()
|
||||
|
||||
可见,原来的逻辑要切入切出,比较繁琐。
|
||||
|
||||
---
|
||||
|
||||
## 📍 重要事项
|
||||
|
||||
如果`<iframe>`跟当前标签页是不同域名的,不能使用页面对象直接查找其中元素,只能先获取其`ChromiumFrame`元素对象,再在这个对象中查找。
|
||||
|
||||
---
|
||||
|
||||
# ✔ `ChromiumFrame`的元素特征
|
||||
|
||||
正如上面所说,`ChromiumFrame`既是元素也是页面,这里说一下其元素方面的用法。
|
||||
|
||||
## 📍 `tab_id`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回`<iframe>`元素所在标签页的 id。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `tag`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回元素名称。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回整个`<iframe>`元素的 outerHTML 文本。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `inner_html`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回 innerHTML 文本。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `attrs`
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
此属性以`dict`形式返回元素所有 attribute 属性。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以`tuple`形式返回元素大小。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `location`
|
||||
|
||||
此属性以`tuple`形式返回元素在主页面中的位置。
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以`tuple`形式返回元素在主页面中的位置,左上角为 (0, 0)。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_displayed`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性返回元素是否可见。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `xpath`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回元素在其页面上的 xpath 路径。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `css_path`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回元素在其页面上的 css selector 路径。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `attr()`
|
||||
|
||||
此方法用于一个获取元素 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| --- |
|
||||
| `attr` | `str` | 必填 | 属性名 |
|
||||
|
||||
- `attr`:属性名
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ------------- |
|
||||
| `str` | 属性值文本 |
|
||||
| `None` | 没有该属性返回`None` |
|
||||
|
||||
**返回:** 属性值文本,没有该属性返回`None`
|
||||
---
|
||||
|
||||
## 📍 `set_attr()`
|
||||
|
||||
此方法用于设置元素的 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------:|:-----:|:---:| --- |
|
||||
| `attr` | `str` | 必填 | 属性名 |
|
||||
| `value` | `str` | 必填 | 属性值 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `remove_attr()`
|
||||
|
||||
此方法用于删除元素的 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:-----:|:---:| --- |
|
||||
| `attr` | `str` | 必填 | 属性名 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 相对定位
|
||||
|
||||
相对定位方法与普通元素一致,详见获取元素章节。
|
||||
@ -197,73 +272,111 @@ page.to_frame.main()
|
||||
|
||||
- `befores()`:返回当前元素后面符合条件的全部兄弟元素或节点组成的列表。
|
||||
|
||||
---
|
||||
|
||||
# ✔ `ChromiumFrame`的页面特征
|
||||
|
||||
## 📍 `url`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回页面当前 url。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `title`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回页面当前 title 文本。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
**类型:**`dict`
|
||||
|
||||
此属性返回页面当前 cookies 内容。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `get()`
|
||||
|
||||
此方法用于实现`<iframe>`页面跳转。
|
||||
此方法用于实现`<iframe>`页面跳转,使用方法与`ChromiumPage`一致。
|
||||
|
||||
```python
|
||||
iframe.get('https://www.runoob.com/css3/css3-tutorial.html')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `refresh()`
|
||||
|
||||
此方法用于刷新页面。
|
||||
|
||||
**参数**: 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
iframe.refresh()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 `ready_state`
|
||||
|
||||
此属性为页面加载状态。
|
||||
**类型:**`str`
|
||||
|
||||
此属性为页面加载状态,包括`'loading'`、`'interactive'`、`'complete'`3 种。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `is_loading`
|
||||
|
||||
**类型:**`bool`
|
||||
|
||||
此属性返回页面是否正在加载。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `active_ele`
|
||||
|
||||
**类型:**`ChromiumElement`
|
||||
|
||||
此属性返回页面中焦点所在元素。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `frame_size`
|
||||
|
||||
**类型:**`Tuple[int, int]`
|
||||
|
||||
此属性以`tuple`形式返回页面大小。
|
||||
|
||||
---
|
||||
|
||||
## 📍 `run_js()`
|
||||
|
||||
此方法用于在`<iframe>`内执行 js 脚本。
|
||||
|
||||
**参数:**
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:---------:|:------:|:-------:| ----------------------------------------------- |
|
||||
| `script` | `str` | 必填 | js 脚本文本 |
|
||||
| `as_expr` | `bool` | `False` | 是否作为表达式运行,为`True`时`args`参数无效 |
|
||||
| `*args` | - | 无 | 传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`... |
|
||||
|
||||
- `script`:js文本
|
||||
| 返回类型 | 说明 |
|
||||
|:-----:| ------ |
|
||||
| `Any` | 脚本执行结果 |
|
||||
|
||||
- `as_expr`:是否作为表达式运行,为`True`时`args`无效
|
||||
|
||||
- `*args`:参数,按顺序在 js 文本中对应 argument[0]、argument[1]...
|
||||
|
||||
**返回:** 运行的结果
|
||||
---
|
||||
|
||||
## 📍 `scroll`
|
||||
|
||||
`ChromiumFrame`的滚动方法与页面或元素是一致的。
|
||||
|
||||
**示例:**
|
||||
|
||||
使`<iframe>`元素向下滚动 300 像素
|
||||
**示例:** 使`<iframe>`元素向下滚动 300 像素
|
||||
|
||||
```python
|
||||
iframe.scroll.down(300)
|
15
docs/6_WebPage/0_introduction.md
Normal file
15
docs/6_WebPage/0_introduction.md
Normal file
@ -0,0 +1,15 @@
|
||||
`WebPage`对象整合了`SessionPage`和`ChromiumPage`,实现了两者之间的互通。
|
||||
|
||||
它既可以操控浏览器,也可以收发数据包,并且会在两者之间同步登录信息。
|
||||
|
||||
它有 d 和 s 两种模式,分别对应操控浏览器和收发数据包。
|
||||
|
||||
`WebPage`可灵活的在两种模式间切换,从而实现一些有趣的用法。
|
||||
|
||||
比如,网站登录代码非常复杂,用数据包实现过于烧脑,我们可以用浏览器处理登录,再通过切换模式用收发数据包的方式去采集数据。
|
||||
|
||||
两种模式的使用逻辑是一致的,跟`ChromiumPage`没有区别,易于上手。
|
||||
|
||||
`WebPage`结构图:
|
||||
|
||||

|
103
docs/6_WebPage/1_create_page_object.md
Normal file
103
docs/6_WebPage/1_create_page_object.md
Normal file
@ -0,0 +1,103 @@
|
||||
本节介绍`WebPage`对象的创建。
|
||||
|
||||
`WebPage`对象拥有两种模式,d 模式用于操控浏览器,s 模式用于收发数据包。
|
||||
|
||||
# ✔️ `WebPage`初始化参数
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
|:--------------------:|:------------------------------------------------:|:------:| ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mode` | `str` | `'d'` | 只能接收`'d'`或`'s'`,即初始选择操控浏览器还是收发数据包 |
|
||||
| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取,默认 10 |
|
||||
| `driver_or_options` | `ChromiumDriver`<br>`ChromiumOptions`<br>`False` | `None` | 默认为`None`表示从 ini 文件读取配置进行初始化<br>接收`ChromiumDriver`时直接接管一个已打开的页面<br>接收`ChromiumOptions`时用该配置启动或接管浏览器<br>如不使用 d 模式功能,接收`False`,避免打包出错 |
|
||||
| `session_or_options` | `Session`<br>`SessionOptions`<br>`False` | `None` | 默认为`None`表示从 ini 文件读取配置进行初始化<br>接收`Session`时直接使用一个已创建的`Session`对象<br>接收`SessionOptions`时用该配置创建`Session`对象<br>如不使用 s 模式功能,接收`False`,避免打包出错 |
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 直接创建
|
||||
|
||||
这种方式代码最简洁,程序会从默认 ini 文件中读取配置,自动生成页面对象。
|
||||
|
||||
创建时,可指定初始模式。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
# 默认d模式创建对象
|
||||
page = WebPage()
|
||||
|
||||
# 指定s模式创建对象
|
||||
page = WebPage('s')
|
||||
```
|
||||
|
||||
d 模式创建`WebPage`对象时会在指定端口启动浏览器,或接管该端口已有浏览器。
|
||||
|
||||
默认情况下,程序使用 9222 端口,浏览器可执行文件路径为`'chrome'`。如路径中没找到浏览器可执行文件,Windows 系统下程序会在注册表中查找路径。如果都没找到,则要用下一种方式手动配置。
|
||||
|
||||
s 模式创建`WebPage`不会打开或接管浏览器。
|
||||
|
||||
!>**注意:**<br>这种方式的程序不能直接打包,因为使用到 ini 文件。可参考“打包程序”一节的方法。
|
||||
|
||||
?>**Tips:**<br>您可以修改配置文件中的配置,实现所有程序都按您的须要进行启动,详见”启动配置“章节。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 通过配置信息创建
|
||||
|
||||
如果须要已指定方式启动浏览器,可使用`ChromiumOptions`和`SessionOptions`。它们的使用在各自的章节已经介绍过,这里只演示如何在`WebPage`创建时使用。
|
||||
|
||||
## 📍 使用方法
|
||||
|
||||
创建两个配置对象后,传递给`WebPage`的初始化方法。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, ChromiumOptions, SessionOptions
|
||||
|
||||
co = ChromiumOptions()
|
||||
so = SessionOptions()
|
||||
|
||||
page = WebPage(driver_or_options=co, session_or_options=so)
|
||||
```
|
||||
|
||||
如果只须要对一个模式的配置进行修改,另一个模式使用 ini 的配置,可以只传入一种配置对象。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, ChromiumOptions
|
||||
|
||||
co = ChromiumOptions()
|
||||
page = WebPage(driver_or_options=co)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 使用指定 ini 文件创建
|
||||
|
||||
以上方法是使用默认 ini 文件中保存的配置信息创建对象,你可以保存一个 ini 文件到别的地方,并在创建对象时指定使用它。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, ChromiumOptinos, SessionOptions
|
||||
|
||||
co = ChromiumOptinos(ini_path=r'./config1.ini')
|
||||
so = SessionOptions(ini_path=r'./config1.ini')
|
||||
|
||||
page = ChromiumPage(addr_driver_opts=co, session_or_options=so)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 传递控制权
|
||||
|
||||
当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
|
||||
|
||||
!>**注意:**<br>传递控制权的时候,记得 driver 和 session 都要传递。
|
||||
|
||||
```python
|
||||
page1 = WebPage()
|
||||
|
||||
# 获取页面对象的浏览器控制器
|
||||
driver = page1.driver
|
||||
# 获取页面对象的内置Session对象
|
||||
session = page1.session
|
||||
|
||||
# 把内置对象在第二个页面对象初始化时传递进去
|
||||
page2 = ChormiumPage(driver_or_options=driver, session_or_options=session)
|
||||
```
|
97
docs/6_WebPage/2_mode_switch.md
Normal file
97
docs/6_WebPage/2_mode_switch.md
Normal file
@ -0,0 +1,97 @@
|
||||
本节介绍`WebPage`的模式切换功能。
|
||||
|
||||
`WebPage`的 d 模式,行为与`ChromiumPage`一致,s 模式行为与`SessionPage`一致。
|
||||
|
||||
使用`change_mode()`方法进行切换。模式切换的时候会同步登录信息。
|
||||
|
||||
# ✔️ `mode`
|
||||
|
||||
**类型:**`str`
|
||||
|
||||
此属性返回`WebPage`当前模式。
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
print(page.mode)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ `change_mode()`
|
||||
|
||||
此方法用于切换`WebPage`运行模式。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:--------------:|:---------------:|:------:| ------------------------------------------------ |
|
||||
| `mode` | `str`<br>`None` | `None` | 接收 's' 或 'd',以切换到指定模式<br>接收`None`则切换到与当前相对的另一个模式 |
|
||||
| `go` | `bool` | `True` | 目标模式是否跳转到原模式的 url |
|
||||
| `copy_cookies` | `bool` | `True` | 切换时是否复制 cookies 到目标模式 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例
|
||||
|
||||
## 📍 切换模式
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
page.get('https://www.baidu.com')
|
||||
print(page.mode)
|
||||
page.change_mode()
|
||||
print(page.mode)
|
||||
print(page.title)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
d
|
||||
s
|
||||
百度一下,你就知道
|
||||
```
|
||||
|
||||
本示例中,执行操作如下:
|
||||
|
||||
- 初始d 模式访问百度
|
||||
|
||||
- 切换到 s 模式,此时会同步登录信息到 s 模式,且在 s 模式访问百度
|
||||
|
||||
- 打印 s 模式访问到的页面标题
|
||||
|
||||
---
|
||||
|
||||
## 📍 自动切换
|
||||
|
||||
在某个模式中使用另一个模式独有的方法,会自动切换模式。
|
||||
|
||||
!>**注意:**<br>这个功能还在调整中,后续版本表现可能和现在不一致,慎用。
|
||||
|
||||
```python
|
||||
page = WebPage('s')
|
||||
page.get('https://www.baidu.com')
|
||||
print(page.mode)
|
||||
print(page.size)
|
||||
print(page.mode)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```python
|
||||
s
|
||||
(1250, 684)
|
||||
d
|
||||
```
|
57
docs/6_WebPage/3_webpage_function.md
Normal file
57
docs/6_WebPage/3_webpage_function.md
Normal file
@ -0,0 +1,57 @@
|
||||
本节介绍`Webpage`独有的功能。
|
||||
|
||||
`WebPage`是`ChromiumPage`和`SessionPage`的集成,因此拥有这两者全部功能。这些功能具体查看相关章节,这里只介绍`WebPage`独有的功能。
|
||||
|
||||
# ✔️ cookies 处理
|
||||
|
||||
## 📍 `cookies_to_session()`
|
||||
|
||||
此方法把浏览器的 cookies 复制到`session`对象。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-----------------:|:------:|:------:| ------------------ |
|
||||
| `copy_user_agent` | `bool` | `True` | 是否复制 user agent 信息 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `cookies_to_session()`
|
||||
|
||||
此方法把`session`对象的 cookies 复制到浏览器。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 关闭对象
|
||||
|
||||
## 📍 `close_driver()`
|
||||
|
||||
此方法关闭内置`ChromiumDriver`对象及浏览器,并切换到 s 模式。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `close_driver()`
|
||||
|
||||
此方法关闭内置`Session`对象及浏览器,并切换到 d 模式。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
---
|
||||
|
||||
## 📍 `quit()`
|
||||
|
||||
此方法彻底关闭内置的`Session`对象和`ChromiumDriver`对象,并关闭浏览器(如已打开)。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
@ -3,7 +3,8 @@
|
||||
也可以在默认配置基础上用简单的方法再次修改,再保存到 ini 文件。
|
||||
也可以保存多个 ini 文件,按不同项目须要调用。
|
||||
|
||||
!> **注意:** <br>ini 文件仅用于管理启动配置,浏览器或`Session`创建后再修改 ini 文件内容是没有效果的。 <br>如果是接管已打开的浏览器,这些设置也没有用。 <br>每次升级本库,ini 文件都会被重置,可另存到其它路径以免重置。
|
||||
!> **注意:** <br>- ini 文件仅用于管理启动配置,页面对象创建后再修改 ini 文件是没用的。 <br>- 如果是接管已打开的浏览器,这些设置也没有用。 <br>- 每次升级本库,ini
|
||||
文件都会被重置,可另存到其它路径以免重置。
|
||||
|
||||
# ✔️ ini 文件内容
|
||||
|
||||
@ -37,11 +38,15 @@ http =
|
||||
https =
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 文件位置
|
||||
|
||||
默认配置文件存放在库文件夹下,文件名为 configs.ini。
|
||||
用户可另存其它配置文件,或从另存的文件读取配置,但默认文件的位置和名称不会改变。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 使用默认配置文件启动
|
||||
|
||||
## 📍 使用页面对象自动加载
|
||||
@ -54,6 +59,8 @@ from DrissionPage import WebPage
|
||||
page = WebPage()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 使用配置对象加载
|
||||
|
||||
这种方式一般用于加载配置后须要进一步修改。
|
||||
@ -67,11 +74,11 @@ so = SessionOptions(ini_path=r'D:\setting.ini')
|
||||
page = WebPage(driver_or_options=do, session_or_options=so)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 使用 Drission 对象加载
|
||||
|
||||
这种方式一般用于加载非默认配置文件,或须在多个页面对象间传递`Drission`对象的情况。
|
||||
|
||||
这是`MixPage`独有的加载方式。
|
||||
这种方式一般用于加载非默认配置文件,或须在多个页面对象间传递`Drission`对象的情况。这是`MixPage`独有的加载方式。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage, Drission
|
||||
@ -80,6 +87,8 @@ ds = Drission(ini_path=r'D:\config1.ini')
|
||||
page = MixPage(drission=ds)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 保存/另存 ini 文件
|
||||
|
||||
```python
|
@ -11,6 +11,8 @@ easy_set 方法存放在`DrissionPage.easy_set`路径中,可用以下方法按
|
||||
from DrissionPage.easy_set import set_headless, set_paths
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 简单示例
|
||||
|
||||
由于 easy_set 方法会直接修改 ini 文件内容,而`ChromiumPage`创建时会默认读取 ini 文件,所以代码看上去比较简洁。
|
||||
@ -28,6 +30,8 @@ set_headless(True)
|
||||
page = ChromiumPage()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 方法介绍
|
||||
|
||||
## 📍 `set_paths()`
|
||||
@ -49,7 +53,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `use_auto_port()`
|
||||
|
||||
@ -64,7 +68,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_argument()`
|
||||
|
||||
@ -78,7 +82,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_user_agent()`
|
||||
|
||||
@ -86,12 +90,12 @@ page = ChromiumPage()
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------------:|:---------------:|:------:| --------------------------- |
|
||||
| `user_agent` | `str` | 无 | user agent文本 |
|
||||
| `user_agent` | `str` | 必填 | user agent文本 |
|
||||
| `ini_path` | `str`<br>`Path` | `None` | 要修改的ini文件路径,为`None`表示默认配置文件 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_proxy()`
|
||||
|
||||
@ -99,12 +103,12 @@ page = ChromiumPage()
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:----------:|:---------------:|:------:| ----------------------------------- |
|
||||
| `proxy` | `str` | 无 | 代理网址和端口,例:`'http://localhost:1080'` |
|
||||
| `proxy` | `str` | 必填 | 代理网址和端口,例:`'http://localhost:1080'` |
|
||||
| `ini_path` | `str`<br>`Path` | `None` | 要修改的ini文件路径,为`None`表示默认配置文件 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_headless()`
|
||||
|
||||
@ -117,7 +121,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_no_imgs()`
|
||||
|
||||
@ -130,7 +134,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_no_js()`
|
||||
|
||||
@ -143,7 +147,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `set_mute()`
|
||||
|
||||
@ -156,7 +160,7 @@ page = ChromiumPage()
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
***
|
||||
---
|
||||
|
||||
## 📍 `show_settings()`
|
||||
|
@ -21,6 +21,8 @@
|
||||
- 支持自定义连接参数
|
||||
- 任务失败自动重试
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 简单示例
|
||||
|
||||
下载一个文件(单线程):
|
||||
@ -56,6 +58,8 @@ page.download_set.by_browser()
|
||||
page.download_set.split(True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 单线程下载
|
||||
|
||||
直接调用页面对象的`download()`方法,可下载一个文件,该方法是阻塞式的,会等待下载完成再往下操作。下载时默认打印下载进度。
|
||||
@ -64,13 +68,13 @@ page.download_set.split(True)
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:---------------:|:------:| ------------------------------------------------ |
|
||||
| `file_url` | `str` | 无 | 文件网址 |
|
||||
| `file_url` | `str` | 必填 | 文件网址 |
|
||||
| `goal_path` | `str`<br>`Path` | `None` | 保存文件夹路径,为`None`则保存在当前目录 |
|
||||
| `rename` | `str` | `None` | 重命名文件名,可不包含后缀 |
|
||||
| `file_exists` | `str` | `None` | 遇到同名文件时的处理方式,可选`'skip'`、`'overwrite'`、`'rename'` |
|
||||
| `data` | `str`<br>`dict` | `None` | post 方式使用的数据,如不为`None`,使用 post 方式发送请求 |
|
||||
| `show_msg` | `bool` | `True` | 是否显示下载进度 |
|
||||
| `**kwargs` | - | 无 | requests的`get()`方法参数 |
|
||||
| `**kwargs` | - | 必填 | requests的`get()`方法参数 |
|
||||
|
||||
| 返回类型 | 返回格式 | 说明 |
|
||||
|:-------:|:------------:| ------------------- |
|
||||
@ -107,7 +111,7 @@ print(res)
|
||||
|
||||
显示:
|
||||
|
||||
```shell
|
||||
```console
|
||||
url:https://www.baidu.com/img/flexible/logo/pc/result.png
|
||||
文件名:img.png
|
||||
目标路径:C:\download
|
||||
@ -116,6 +120,8 @@ url:https://www.baidu.com/img/flexible/logo/pc/result.png
|
||||
('success', 'C:\\download\\img.png')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 多线程并发下载
|
||||
|
||||
您可以添加数量不限的下载任务,程序会自动调配线程去完成这些任务。
|
||||
@ -128,13 +134,13 @@ url:https://www.baidu.com/img/flexible/logo/pc/result.png
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:---------------:|:------:| ----------------------------------------------------------------- |
|
||||
| `file_url` | `str` | 无 | 文件网址 |
|
||||
| `file_url` | `str` | 必填 | 文件网址 |
|
||||
| `goal_path` | `str`<br>`Path` | `None` | 保存文件夹路径,为`None`则保存在当前目录 |
|
||||
| `rename` | `str` | `None` | 重命名文件名,可不包含后缀 |
|
||||
| `file_exists` | `str` | `None` | 遇到同名文件时的处理方式,可选`'skip'`、`'overwrite'`、`'rename'` |
|
||||
| `data` | `str`<br>`dict` | `None` | post 方式使用的数据,如不为`None`,使用 post 方式发送请求 |
|
||||
| `split` | `bool` | `None` | 是否允许多线程分块下载,为`None`则使用下载器内置设置,默认为`True`<br>默认大于 50MB 的文件使用多线程分块下载 |
|
||||
| `**kwargs` | - | 无 | requests的`get()`方法参数 |
|
||||
| `**kwargs` | - | 必填 | requests的`get()`方法参数 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:---------:| ---------------------------------------------------------------------------- |
|
||||
@ -158,12 +164,14 @@ mission = page.download.add(url, save_path)
|
||||
print(mission.rate, mission.info)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```shell
|
||||
```console
|
||||
90% '下载中'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 接管浏览器下载任务
|
||||
|
||||
## 📍 切换下载方式
|
||||
@ -184,11 +192,15 @@ page.download_set.by_browser()
|
||||
|
||||
!>**注意:**<br>接管浏览器下载任务后会使用 get 方式下载,如果是需要 post 的请求,可能不能正确下载。
|
||||
|
||||
---
|
||||
|
||||
## 📍 等待下载开始
|
||||
|
||||
在浏览器中点击下载按钮后,有时下载不会立即触发,这时如果过快进行其它操作,可能导致一些意想不到的问题。因此设计了`wait_download_begin()`
|
||||
方法,用于等待下载动作的开始,以便正确接管。可控制浏览器的页面对象`ChromiumPage`和`WebPage`拥有此方法。
|
||||
|
||||
!>**注意:**<br>如果网站须要很长时间准备下载的文件,请设置一个足够长的超时时间。
|
||||
|
||||
### 🔸 `wait_download_begin()`
|
||||
|
||||
此方法会阻塞程序,等待下载动作触发。如到达超时时间仍未触发,则返回`False`。
|
||||
@ -208,6 +220,8 @@ page('#download_btn').click()
|
||||
page.wait_download_begin()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 查看任务信息
|
||||
|
||||
用单线程方式下载,会阻塞程序直到下载完成,因此无须查看任务信息。
|
||||
@ -239,6 +253,8 @@ mission_id = mission.id
|
||||
mission = page.download.get_mission(mission_id)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取全部任务对象
|
||||
|
||||
使用页面对象的`download.missions`属性,可以获取所有下载任务。该属性返回一个`dict`,保存了所有下载任务。以任务对象的`id`为 key。
|
||||
@ -250,7 +266,7 @@ page.download('http://xxxxx/xxx1.pdf')
|
||||
print(page.download.missions)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{
|
||||
@ -260,6 +276,8 @@ print(page.download.missions)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📍 获取下载失败的任务
|
||||
|
||||
使用`download.get_failed_missions()`方法,可以获取下载失败的任务列表。
|
||||
@ -271,7 +289,7 @@ page.download('http://xxxxx/xxx1.pdf')
|
||||
print(page.download.get_failed_missions()
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
[
|
||||
@ -283,6 +301,8 @@ print(page.download.get_failed_missions()
|
||||
|
||||
?>**Tips:**<br>获取失败任务对象后,可从其`data`属性读取任务内容,以便记录日志或择机重试。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 下载设置
|
||||
|
||||
主要的下载设置使用`download_set`内置方法进行,更多运行参数使用`download`属性的子属性进行。
|
||||
@ -295,7 +315,7 @@ print(page.download.get_failed_missions()
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:------:|:---------------:|:---:| ------------------ |
|
||||
| `path` | `str`<br>`Path` | 无 | 文件保存路径,绝对路径和相对路径均可 |
|
||||
| `path` | `str`<br>`Path` | 必填 | 文件保存路径,绝对路径和相对路径均可 |
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
@ -307,6 +327,8 @@ page.download_set.save_path(r'D:\tmp')
|
||||
|
||||
?>**Tips:**<br>- 保存路径可指定不存在的文件夹,程序会自动创建。<br>- 设置默认保存路径后,每个任务仍可在创建时指定自己的保存路径,以覆盖默认设置。
|
||||
|
||||
---
|
||||
|
||||
## 📍 设置下载方式
|
||||
|
||||
### 🔸 `download_set.by_DownloadKit()`
|
||||
@ -317,6 +339,8 @@ page.download_set.save_path(r'D:\tmp')
|
||||
|
||||
此方法用于设置当前页面对象使用浏览器下载工具下载文件。
|
||||
|
||||
---
|
||||
|
||||
## 📍 设置重名文件处理方法
|
||||
|
||||
下载过程中可能遇到保存路径已存在同名文件,`DownloadKit`提供 3 种处理方法。
|
||||
@ -346,6 +370,8 @@ xxx_1.pdf
|
||||
xxx_2.pdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔸 `download_set.if_file_exists.skip()`
|
||||
|
||||
遇到同名文件时,跳过。同时任务对象的`result`属性设置为`'skip'`。
|
||||
@ -365,6 +391,8 @@ page.download('http://xxxxx/xxx.pdf')
|
||||
xxx.pdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔸 `download_set.if_file_exists.overwrite()`
|
||||
|
||||
遇到同名文件时,覆盖。
|
||||
@ -373,6 +401,8 @@ xxx.pdf
|
||||
|
||||
?>**Tips:**<br>- 除了整体设置,还可以在创建任务时单独设置该任务的处理方式。<br>- 文件名如遇到`'?'`、`'\'`等非法字符,会自动替换为空格。
|
||||
|
||||
---
|
||||
|
||||
## 📍 设置大文件是否分块
|
||||
|
||||
`DownloadKit`具备多线程下载大文件功能,在文件超过指定大小时(默认 50MB),可对文件进行多线程分块下载,每个线程负责 50MB 的下载,以提高下载速度。这个功能默认是关闭的,您可以设置是否开启。
|
||||
@ -392,6 +422,8 @@ page.download_set.split(on_off=False)
|
||||
?>**Tips:**
|
||||
除了整体设置,还可以在创建任务时单独设置该任务是否使用分块下载。
|
||||
|
||||
---
|
||||
|
||||
## 📍运行参数设置
|
||||
|
||||
运行参数主要包括可使用线程上限、连接失败重试次数、重试间隔。
|
||||
@ -408,6 +440,8 @@ page.download_set.split(on_off=False)
|
||||
page.download.roads = 20 # 允许最多使用20个线程进行下载
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔸 `download.retry`
|
||||
|
||||
此属性用于设置连接失败时重试次数,默认为 3。
|
||||
@ -416,6 +450,8 @@ page.download.roads = 20 # 允许最多使用20个线程进行下载
|
||||
page.download.roads = 5 # 设置连接失败时重试5次
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔸 `download.interval`
|
||||
|
||||
此属性用于设置连接失败时重试间隔,默认为 5 秒。
|
109
docs/7_advance/4_accelerate_collecting.md
Normal file
109
docs/7_advance/4_accelerate_collecting.md
Normal file
@ -0,0 +1,109 @@
|
||||
本节演示一个能够大幅加快浏览器页面数据采集的黑科技。
|
||||
|
||||
# ✔️ 示例
|
||||
|
||||
我们找一个比较大的页面来演示,比如网页首页:[https://www.163.com]([https://www.163.com](https://www.163.com))
|
||||
|
||||
我们数一下这个网页内的`<a>`元素数量:
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
page = ChromiumPage()
|
||||
page.get('https://www.163.com')
|
||||
print(len(page('t:body').eles('t:a')
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
1613
|
||||
```
|
||||
|
||||
嗯,数量不少,可以看出效果。
|
||||
|
||||
加入现在我们的任务是打印所有链接的文本,常规做法是遍历所有元素,然后打印。
|
||||
|
||||
这里引入一个计时工具,可以标记一段代码运行时间。您也可以用其它方法计时。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
from TimePinner import Pinner # 导入计时工具
|
||||
|
||||
pinner = Pinner() # 创建计时器对象
|
||||
page = ChromiumPage()
|
||||
page.get('https://www.163.com')
|
||||
|
||||
pinner.pin() # 标记开始记录
|
||||
|
||||
# 获取所有链接对象并遍历
|
||||
links = page('t:body').eles('t:a')
|
||||
for lnk in links:
|
||||
print(lnk.text)
|
||||
|
||||
pinner.pin('用时') # 记录并打印时间
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
0.0
|
||||
|
||||
网络大过年_网易政务_网易网
|
||||
网易首页
|
||||
...中间省略...
|
||||
不良信息举报 Complaint Center
|
||||
廉正举报
|
||||
用时:4.057772700001806
|
||||
```
|
||||
|
||||
用时 4 秒。
|
||||
|
||||
现在,我们稍微修改一个小小的地方。
|
||||
|
||||
把`page('t:body').eles('t:a')`改成`page('t:body').s_eles('t:a')`,然后再执行一次。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
from TimePinner import Pinner # 导入计时工具
|
||||
|
||||
pinner = Pinner() # 创建计时器对象
|
||||
page = ChromiumPage()
|
||||
page.get('https://www.163.com')
|
||||
|
||||
pinner.pin() # 标记开始记录
|
||||
|
||||
# 获取所有链接对象并遍历
|
||||
links = page('t:body').s_eles('t:a')
|
||||
for lnk in links:
|
||||
print(lnk.text)
|
||||
|
||||
pinner.pin('用时') # 记录并打印时间
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
0.0
|
||||
|
||||
网络大过年_网易政务_网易网
|
||||
网易首页
|
||||
...中间省略...
|
||||
不良信息举报 Complaint Center
|
||||
廉正举报
|
||||
用时:0.2797656000002462
|
||||
```
|
||||
|
||||
神奇不?原来 4 秒的采集时间现在只需 0.28 秒。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 解读
|
||||
|
||||
`s_eles()`与`eles()`的区别在于前者会把整个页面转变成一个静态页面,再在其中获取静态元素,因为静态元素是纯文本的,没有各种属性、交互等等消耗资源的部分,所有运行速度非常快。
|
||||
|
||||
作者曾经采集过一个非常复杂的页面,动态元素用时 30 秒,转静态元素就只要 0.X 秒,加速效果非常明显。
|
||||
|
||||
我们可以获取页面中内容容器(示例中的`<body>`),把它转换成静态元素,再在其中获取信息。
|
||||
|
||||
当然,静态元素没有交互功能,但它只是副本,不会影响原来的动态元素。
|
@ -31,6 +31,8 @@ drission = Drission(ini_path=r'.\configs.ini') # ini文件放在程序相同路
|
||||
page = MixPage(drission=drission)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 不使用 ini
|
||||
|
||||
这种方法须把所有配置信息写到代码里。
|
||||
@ -65,6 +67,8 @@ page = MixPage(driver_options=do, session_options=so)
|
||||
page = WebPage(driver_or_options=do, session_or_options=False)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 实用示例
|
||||
|
||||
通常,我会把一个绿色浏览器和打包后的 exe 文件放在一起,程序中用相对路径指向该浏览器,这样拿到别的电脑也可以正常实用。
|
@ -4,14 +4,12 @@
|
||||
|
||||
做数据采集的时候,我们往往从 DOM 中去获取解析后数据的,可能存在 数据不全、加载响应不及时、难以判断加载完成等问题。
|
||||
|
||||
因此开发了一个监听器,专门用于抓取 Chrome 浏览器数据包。
|
||||
因此开发了一个监听器,专门用于抓取 Chromium 内核浏览器数据包。
|
||||
|
||||
由于该工具不依赖 DrissionPage,现已独立发布为一个库,但仍然可以在 DrissionPage 中导入。
|
||||
|
||||
!> 为了便于维护,该工具用法请移步 [FlowViewer](https://gitee.com/g1879/FlowViewer) 查看。
|
||||
|
||||
|
||||
|
||||
# ✔️ 简单示例
|
||||
|
||||
```python
|
@ -14,10 +14,15 @@ page = SessionPage(session)
|
||||
|
||||
# 使用页面对象
|
||||
page.get('http://www.baidu.com')
|
||||
# 输出:百度一下
|
||||
print(page.ele('#su').text)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
百度一下
|
||||
```
|
||||
|
||||
# ✔️ DriverPage
|
||||
|
||||
```python
|
||||
@ -31,6 +36,11 @@ page = DriverPage(driver)
|
||||
|
||||
# 使用页面对象
|
||||
page.get('http://www.baidu.com')
|
||||
# 输出:百度一下
|
||||
print(page.ele('#su').text)
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
百度一下
|
||||
```
|
@ -106,8 +106,8 @@ response = session.head('https://www.baidu.com')
|
||||
print(response.headers)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```shell
|
||||
```console
|
||||
{'Accept-Ranges': 'bytes', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Length': '277', 'Content-Type': 'text/html', 'Date': 'Tue, 04 Jan 2022 06:49:18 GMT', 'Etag': '"575e1f72-115"', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:26 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18'}
|
||||
```
|
@ -115,17 +115,21 @@ Hello World!
|
||||
|
||||
```python
|
||||
texts = ele.texts()
|
||||
print(e.texts(text_node_only=True))
|
||||
# 输出:['Hello World!', '行元素']
|
||||
print(e.texts(text_node_only=True))
|
||||
print(e.texts())
|
||||
```
|
||||
|
||||
print(e.texts())
|
||||
# 输出:['Hello World!']
|
||||
**输出:**
|
||||
|
||||
```console
|
||||
['Hello World!', '行元素']
|
||||
['Hello World!']
|
||||
```
|
||||
|
||||
## 📍 `comments`
|
||||
|
||||
```python
|
||||
comments = ele.comments
|
||||
comments = ele.comments
|
||||
# 返回:[<!--这是注释-->]
|
||||
```
|
||||
|
@ -160,9 +160,9 @@ ele.run_script('arguments[0].click()')
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:---------:|:----:|:------------:|
|
||||
| display() | 无 | 等待元素从 DOM 显示 |
|
||||
| hidden() | 无 | 等待元素从 DOM 隐藏 |
|
||||
| delete() | 无 | 等待元素从 DOM 删除 |
|
||||
| display() | 无 | 等待元素从 DOM 显示 |
|
||||
| hidden() | 无 | 等待元素从 DOM 隐藏 |
|
||||
| delete() | 无 | 等待元素从 DOM 删除 |
|
||||
|
||||
这些方法返回布尔值,代表是否等待成功。
|
||||
|
||||
@ -301,11 +301,11 @@ ele1.drag_to((50, 50))
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:-----------------:|:------:|:----------------:|
|
||||
| to_top() | 无 | 滚动到顶端,水平位置不变 |
|
||||
| to_bottom() | 无 | 滚动到底端,水平位置不变 |
|
||||
| to_half() | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| to_rightmost() | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| to_leftmost() | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| to_top() | 无 | 滚动到顶端,水平位置不变 |
|
||||
| to_bottom() | 无 | 滚动到底端,水平位置不变 |
|
||||
| to_half() | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| to_rightmost() | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| to_leftmost() | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| to_location(x, y) | 滚动条坐标值 | 滚动到指定位置 |
|
||||
| up(pixel) | 滚动的像素 | 向上滚动若干像素,水平位置不变 |
|
||||
| down(pixel) | 滚动的像素 | 向下滚动若干像素,水平位置不变 |
|
@ -49,7 +49,7 @@ for i in p.get_cookies(as_dict=False, all_domains=True):
|
||||
print(i)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'domain': '.baidu.com', 'domain_specified': True, ......}
|
||||
@ -135,7 +135,7 @@ print(r.status_code)
|
||||
print(page.timeouts)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
{'implicit': 10, 'pageLoad': 30.0, 'script': 30.0}
|
@ -46,7 +46,7 @@ print('当前模式:', page.mode)
|
||||
print('登录后title:', page.title)
|
||||
```
|
||||
|
||||
输出:
|
||||
**输出:**
|
||||
|
||||
```
|
||||
当前模式:d
|
||||
@ -153,9 +153,9 @@ page.set_cookies(cookies)
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:-----------:|:----:|:------------:|
|
||||
| `display()` | 无 | 等待元素从 DOM 显示 |
|
||||
| `hidden()` | 无 | 等待元素从 DOM 隐藏 |
|
||||
| `delete()` | 无 | 等待元素从 DOM 删除 |
|
||||
| `display()` | 无 | 等待元素从 DOM 显示 |
|
||||
| `hidden()` | 无 | 等待元素从 DOM 隐藏 |
|
||||
| `delete()` | 无 | 等待元素从 DOM 删除 |
|
||||
|
||||
这些方法返回布尔值,代表是否等待成功。
|
||||
|
||||
@ -304,15 +304,15 @@ page.run_cdp('Page.stopLoading')
|
||||
调用此属性返回一个`ToFrame`对象,调用该对象的方法实现焦点转移。
|
||||
这些方法返回值为当前页面对象,可实现下一步的链式操作。
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:-----------------:|:-------:|:----------------:|
|
||||
| `main()` | 无 | 切换到顶层框架 |
|
||||
| `main()` | 无 | 切换到顶层框架 |
|
||||
| `parent(level)` | 第几层上级框架 | 切换到上级框架,可指定多层 |
|
||||
| `by_id(id)` | id 属性 | 切换到`id`为该参数的框架 |
|
||||
| `by_id(id)` | id 属性 | 切换到`id`为该参数的框架 |
|
||||
| `by_name(name)` | name 属性 | 切换到`name`为该参数的框架 |
|
||||
| `by_index(index)` | 序号 | 切换到页面第几个框架,0 开始 |
|
||||
| `by_loc(loc)` | 定位符 | 切换到定位符所指框架 |
|
||||
| `by_ele(ele)` | 框架元素 | 传入框架元素,切换到该框架 |
|
||||
| `by_index(index)` | 序号 | 切换到页面第几个框架,0 开始 |
|
||||
| `by_loc(loc)` | 定位符 | 切换到定位符所指框架 |
|
||||
| `by_ele(ele)` | 框架元素 | 传入框架元素,切换到该框架 |
|
||||
|
||||
```python
|
||||
# 切换到主框架
|
||||
@ -443,13 +443,13 @@ page.close_other_tabs(reserve_list)
|
||||
此属性用于以某种方式滚动页面。
|
||||
调用此属性返回一个`Scroll`对象,调用该对象方法实现各种方式的滚动。
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
|:-------------------:|:------:|:----------------:|
|
||||
| `to_top()` | 无 | 滚动到顶端,水平位置不变 |
|
||||
| `to_bottom()` | 无 | 滚动到底端,水平位置不变 |
|
||||
| `to_half()` | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| `to_rightmost()` | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| `to_leftmost()` | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| `to_top()` | 无 | 滚动到顶端,水平位置不变 |
|
||||
| `to_bottom()` | 无 | 滚动到底端,水平位置不变 |
|
||||
| `to_half()` | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| `to_rightmost()` | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| `to_leftmost()` | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| `to_location(x, y)` | 滚动条坐标值 | 滚动到指定位置 |
|
||||
| `up(pixel)` | 滚动的像素 | 向上滚动若干像素,水平位置不变 |
|
||||
| `down(pixel)` | 滚动的像素 | 向下滚动若干像素,水平位置不变 |
|
@ -8,10 +8,14 @@
|
||||
|
||||
按`F12`,可以看到每本图书都在`class`属性为`subject-item`的元素中,可批量获取,然后再在其中获取`<img>`元素保存图片。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 编码思路
|
||||
|
||||
为了演示元素对象的`save()`方法,这里我们使用浏览器操作,把图片文件保存到本地 imgs 文件夹。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
以下代码可直接运行。
|
||||
@ -37,6 +41,8 @@ for _ in range(4):
|
||||
page('后页>').click(wait_loading=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结果
|
||||
|
||||

|
@ -10,6 +10,8 @@
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# ✔️ 编码思路
|
||||
|
||||
有`id`属性的元素获取非常简单。两个输入框直接用`id`属性定位即可。
|
||||
@ -17,6 +19,8 @@
|
||||
|
||||
由于使用浏览器登录,这里用`ChromiumPage`来控制浏览器。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
```python
|
||||
@ -36,6 +40,8 @@ page.ele('#user_password').input('您的密码')
|
||||
page.ele('@value=登 录').click()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结果
|
||||
|
||||
登录成功。
|
@ -6,10 +6,14 @@
|
||||
|
||||
采集目标:排名、电影名称、演员、上映时间、分数
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 编码思路
|
||||
|
||||
按`F12`,可以看到每个电影信息都包含在`<dd>`元素中,因此可批量获取`<dd>`元素,遍历它们并再从其中获取每个电影的信息。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
以下代码可直接运行。
|
||||
@ -49,6 +53,8 @@ while True:
|
||||
recorder.record()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结果
|
||||
|
||||
程序生成一个结果文件 data.csv,内容如下:
|
@ -10,12 +10,16 @@
|
||||
|
||||
按`F12`,可以看到每个标题元素的`class`属性均为`title project-namespace-path`,可批量获取。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 编码思路
|
||||
|
||||
虽然 gitee 开源项目列表可以用 s 模式采集,但现在为了演示多标签页操作,还是使用浏览器进行操作。
|
||||
|
||||
使用`ChromiumPage`的`get_loc()`方法,分别获取两个标签页的对象,传入不同线程进行操作。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
以下代码可直接运行。
|
||||
@ -77,6 +81,8 @@ if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结果
|
||||
|
||||
程序生成一个结果文件 data.csv,内容如下:
|
@ -16,12 +16,16 @@
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# ✔️ 编码思路
|
||||
|
||||
按照页面规律,我们可以获取所有`class`属性为`preview circle`的元素,然后遍历它们,逐个获取图片路径,以及在后面一个元素中获取产品名称。再将其下载。
|
||||
|
||||
并且这个网址页面结构非常简单,没有使用 js 生成的页面,可以直接使用 s 模式访问。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 示例代码
|
||||
|
||||
```python
|
||||
@ -53,6 +57,8 @@ for div in divs:
|
||||
|
||||
?> **Tips:** <br>程序中无须创建`imgs`文件夹,`download()`方法会自动创建。
|
||||
|
||||
---
|
||||
|
||||
# ✔️ 结果
|
||||
|
||||

|
@ -28,6 +28,8 @@ python 版本:3.6 及以上
|
||||
|
||||
**联系邮箱:** g1879@qq.com
|
||||
|
||||
---
|
||||
|
||||
# 📕 背景
|
||||
|
||||
用 requests 做数据采集面对要登录的网站时,要分析数据包、JS 源码,构造复杂的请求,往往还要应付验证码、JS 混淆、签名参数等反爬手段,门槛较高。若数据是由 JS 计算生成的,还须重现计算过程,体验不好,开发效率不高。
|
||||
@ -38,10 +40,14 @@ python 版本:3.6 及以上
|
||||
|
||||
以前的版本是对 selenium 进行重新封装实现的。从 3.0 开始,作者另起炉灶,对底层进行了重新开发,摆脱对 selenium 的依赖,增强了功能,提升了运行效率。
|
||||
|
||||
---
|
||||
|
||||
# 💡 理念
|
||||
|
||||
简洁!易用 !方便!
|
||||
|
||||
---
|
||||
|
||||
# ☀️ 特性
|
||||
|
||||
作者经过长期实践,踩过无数坑,总结出的经验全写到这个库里了。
|
||||
@ -90,11 +96,15 @@ python 版本:3.6 及以上
|
||||
|
||||
- 还有很多细节,这里不一一列举,欢迎实际使用中体验:D
|
||||
|
||||
---
|
||||
|
||||
# 🖐🏻 免责声明
|
||||
|
||||
请勿将 DrissionPage 应用到任何可能会违反法律规定和道德约束的工作中,请友善使用 DrissionPage,遵守蜘蛛协议,不要将 DrissionPage 用于任何非法用途。如您选择使用 DrissionPage
|
||||
即代表您遵守此协议,作者不承担任何由于您违反此协议带来任何的法律风险和损失,一切后果由您承担。
|
||||
|
||||
---
|
||||
|
||||
# ☕ 请我喝咖啡
|
||||
|
||||
如果本项目对您有所帮助,不妨请作者我喝杯咖啡 :)
|
||||
|
@ -1,302 +0,0 @@
|
||||
在入门指南的上手示例一节,我们已经初步了解如何创建页面对象,本节进一步介绍更多功能。
|
||||
|
||||
常用的页面对象有 3 种:
|
||||
|
||||
- `WebPage`:整合 d 模式和 s 模式于一体的页面对象
|
||||
|
||||
- `ChromiumPage`:单纯用于操作浏览器的页面对象
|
||||
|
||||
- `SessionPage`:单纯用于收发数据包的页面对象
|
||||
|
||||
这 3 种页面对象的使用逻辑是一致的,使用时可根据实际须要选择使用。
|
||||
|
||||
!>**注意:**<br>如果有已经打开的同类型浏览器,请先关闭,或者按照下文“多浏览器共存”内容设置。否则会报错。
|
||||
|
||||
# ✔️ 直接创建
|
||||
|
||||
这种方式代码最简洁,程序会从配置文件中读取配置,自动生成页面对象。可以保持代码简洁。
|
||||
在基本概念一节我们提到过,本库使用配置文件记录常用配置信息,它会自动读取配置。
|
||||
|
||||
```python
|
||||
# 默认以 d 模式创建页面对象
|
||||
page = WebPage()
|
||||
|
||||
# 指定以 s 模式创建页面对象
|
||||
page = WebPage('s')
|
||||
|
||||
# 用 ChromiumPage 创建页面对象
|
||||
page = ChromiumPage()
|
||||
|
||||
# 用 SessionPage 创建页面对象
|
||||
page = SessionPage()
|
||||
```
|
||||
|
||||
默认配置文件中,程序使用 9222 端口启动浏览器,浏览器路径为`'chrome'`。如路径中没找到浏览器执行文件,Windows 系统下程序会在注册表中查找路径。
|
||||
|
||||
如果都没找到,则要用下一种方式手动配置路径。
|
||||
|
||||
# ✔️ 通过配置信息创建
|
||||
|
||||
本库有两种管理配置信息的对象,`ChromiumOptions`和`SessionOptions`,分别对应控制浏览器和收发数据包的配置。须要时,可以创建相应的配置对象进行设置。
|
||||
|
||||
## 📍 `ChromiumOptions`
|
||||
|
||||
`ChromiumOptions`用于管理创建浏览器时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| ----------- | ------ | ------ | ------------------------ |
|
||||
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
|
||||
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
|
||||
|
||||
!>**注意:**<br>浏览器创建后再修改这个配置是没有效果的。
|
||||
|
||||
```python
|
||||
# 导入 ChromiumOptions
|
||||
from DrissionPage import WebPage, ChromiumOptions
|
||||
|
||||
# 创建浏览器配置对象,指定浏览器路径
|
||||
do = ChromiumOptions().set_paths(browser_path=r'D:\chrome.exe')
|
||||
# 用该配置创建页面对象
|
||||
page = WebPage(driver_or_options=do)
|
||||
```
|
||||
|
||||
## 📍 `SessionOptions`
|
||||
|
||||
`SessionOptions`用于管理创建`Session`对象时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| ----------- | ------ | ------ | ------------------------ |
|
||||
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
|
||||
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
|
||||
|
||||
!>**注意:**<br> `Session`对象创建后再修改这个配置是没有效果的。
|
||||
|
||||
```python
|
||||
# 导入 SessionOptions
|
||||
from DrissionPage import SessionPage, SessionOptions
|
||||
|
||||
proxies = {'http': 'http://127.0.0.1:1080',
|
||||
'https': 'http://127.0.0.1:1080'}
|
||||
|
||||
# 创建配置对象,不从 ini 文件读取,并设置代理信息
|
||||
so = SessionOptions(read_file=False).set_proxies(proxies)
|
||||
# 用该配置创建页面对象
|
||||
page = SessionPage(session_or_options=so)
|
||||
```
|
||||
|
||||
`WebPage`创建时浏览器配置和`Session`对象配置是可以同时使用的,不会互相影响。
|
||||
|
||||
```python
|
||||
page = WebPage(session_or_options=so, driver_or_options=do)
|
||||
```
|
||||
|
||||
?>**Tips:**<br>您可以把配置保存到配置文件以后自动读取,详见”启动配置“章节。
|
||||
|
||||
## 📍 直接指定地址创建
|
||||
|
||||
`ChromiumPage`可以直接接收浏览器地址来创建,格式为 'ip:port'。
|
||||
|
||||
```python
|
||||
page = ChromiumPage(addr_driver_opts='127.0.0.1:9333')
|
||||
```
|
||||
|
||||
## 📍 使用其它 ini 文件创建
|
||||
|
||||
以上方法是使用默认 ini 文件中保存的配置信息创建对象,你可以保存一个 ini 文件到别的地方,并在创建对象时指定使用它。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, DriverOptinos
|
||||
|
||||
# 创建配置对象时指定要读取的ini文件路径
|
||||
do = DriverOptinos(ini_path=r'./config1.ini')
|
||||
# 使用该配置对象创建页面
|
||||
page = WebPage(driver_or_options=do)
|
||||
```
|
||||
|
||||
# ✔️ 传递控制权
|
||||
|
||||
当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
|
||||
|
||||
这也可以实现多个页面对象共同控制一个浏览器。
|
||||
|
||||
## 📍 `ChromiumPage`传递驱动器
|
||||
|
||||
```python
|
||||
# 创建一个页面
|
||||
page1 = ChormiumPage()
|
||||
# 获取页面对象的浏览器控制器
|
||||
driver = page1.driver
|
||||
# 把控制器对象在第二个页面对象初始化时传递进去
|
||||
page2 = ChormiumPage(driver_or_options=driver)
|
||||
```
|
||||
|
||||
## 📍 `SessionPage`传递`Session`对象
|
||||
|
||||
```python
|
||||
# 创建一个页面
|
||||
page1 = SessionPage()
|
||||
# 获取页面对象内置的Session对象
|
||||
session = page1.session
|
||||
# 在第二个页面对象初始化时传递该对象
|
||||
page2 = SessionPage(session_or_options=session)
|
||||
```
|
||||
|
||||
## 📍 `WebPage`传递两种模式控制权
|
||||
|
||||
```python
|
||||
# 创建一个页面
|
||||
page1 = WebPage()
|
||||
# 获取页面对象的浏览器控制器
|
||||
driver = page1.driver
|
||||
# 获取页面对象的Session对象
|
||||
session = page1.session
|
||||
# 把两个控制器对象在第二个页面对象初始化时传递进去
|
||||
page2 = WebPage(driver_or_options=driver, session_or_options=session)
|
||||
```
|
||||
|
||||
# ✔️ 接管已打开的浏览器
|
||||
|
||||
页面对象创建时,只要指定的 ip:port 中已有浏览器在运行,就会直接接管。无论浏览器是下面哪种方式启动的。
|
||||
|
||||
## 📍 用程序启动的浏览器
|
||||
|
||||
默认情况下,创建浏览器页面对象时会自动启动一个浏览器。只要这个浏览器不关闭,下次运行程序时会接管同一个浏览器继续操作(配置的 ip:port 信息不变)。
|
||||
|
||||
这种方式极大地方便了程序的调试,使程序不必每次重新开始,可以单独调试某个功能。
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
# 创建对象同时启动浏览器,如果浏览器已经存在,则接管它
|
||||
page = ChromiumPage()
|
||||
```
|
||||
|
||||
## 📍 手动打开的浏览器
|
||||
|
||||
如果须要手动打开浏览器再接管,可以这样做:
|
||||
|
||||
- 右键点击浏览器图标,选择属性
|
||||
|
||||
- 在“目标”路径后面加上` --remote-debugging-port=端口号`(注意最前面有个空格)
|
||||
|
||||
- 点击确定
|
||||
|
||||
- 在程序中的浏览器配置中指定接管该端口浏览器
|
||||
|
||||
文件快捷方式的目标路径设置:
|
||||
|
||||
```
|
||||
D:\chrome.exe --remote-debugging-port=9222
|
||||
```
|
||||
|
||||
程序代码:
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage, ChromiumOptions
|
||||
|
||||
do = ChromiumOptions().set_paths(local_port=9222)
|
||||
page = WebPage(driver_or_options=do)
|
||||
```
|
||||
|
||||
!> **注意:**<br>接管浏览器时只有`local_port`、`debugger_address`参数是有效的。
|
||||
|
||||
## 📍 bat 文件启动的浏览器
|
||||
|
||||
可以把上一种方式的目标路径设置写进 bat 文件(Windows系统),运行 bat 文件来启动浏览器,再用程序接管。
|
||||
|
||||
新建一个文本文件,在里面输入以下内容(路径改为自己电脑的):
|
||||
|
||||
```console
|
||||
"D:\chrome.exe" --remote-debugging-port=9222
|
||||
```
|
||||
|
||||
保存后把后缀改成 bat,然后双击运行就能在 9222 端口启动一个浏览器。程序代码则和上一个方法一致。
|
||||
|
||||
# ✔️ 多浏览器共存
|
||||
|
||||
## 📍 用程序启动的浏览器
|
||||
|
||||
如果想要同时操作多个浏览器,或者自己在使用其中一个上网,同时控制另外几个跑自动化,就须要给这些被程序控制的浏览器设置单独的**端口**和**用户文件夹**,否则会造成冲突。具体用`ChromiumOptions`对象进行设置,示例如下:
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
# 创建多个配置对象,每个指定不同的端口号和用户文件夹路径
|
||||
do1 = ChromiumOptions().set_paths(local_port=9111, user_data_path=r'D:\data1')
|
||||
do2 = ChromiumOptions().set_paths(local_port=9222, user_data_path=r'D:\data2')
|
||||
|
||||
# 创建多个页面对象
|
||||
page1 = ChromiumPage(addr_driver_opts=do1)
|
||||
page2 = ChromiumPage(addr_driver_opts=do2)
|
||||
|
||||
# 每个页面对象控制一个浏览器
|
||||
page1.get('https://www.baidu.com')
|
||||
page2.get('http://www.163.com')
|
||||
```
|
||||
|
||||
?>**Tips:**<br>每个浏览器都要设置独立的端口号和用户文件夹,二者缺一不可。
|
||||
|
||||
## 📍 bat 文件启动的浏览器
|
||||
|
||||
如果要接管多个 bat 文件打开的浏览器,每个浏览器的参数都要添加`--remote-debugging-port`和`--user-data-dir`参数。浏览器路径则是一样的。示例如下:
|
||||
|
||||
bat 文件1
|
||||
|
||||
```
|
||||
"D:\chrome.exe" --remote-debugging-port=9111 --user-data-dir=D:\data1
|
||||
```
|
||||
|
||||
bat 文件2
|
||||
|
||||
```
|
||||
"D:\chrome.exe“ --remote-debugging-port=9222 --user-data-dir=D:\data2
|
||||
```
|
||||
|
||||
程序代码:
|
||||
|
||||
```python
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
|
||||
do1 = ChromiumOptions().set_paths(local_port=9111)
|
||||
do2 = ChromiumOptions().set_paths(local_port=9222)
|
||||
|
||||
page1 = ChromiumPage(addr_driver_opts=do1)
|
||||
page2 = ChromiumPage(addr_driver_opts=do2)
|
||||
```
|
||||
|
||||
# ✔️ 页面对象初始化 API
|
||||
|
||||
## 📍 `ChromiumPage`
|
||||
|
||||
`ChroumiumPage`对象纯粹用于操作浏览器,不能切换模式。一个该对象对应一个浏览器。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | -------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
|
||||
| `addr_driver_opts` | `str`<br>`ChromiumDriver` | `None` | 浏览器启动配置或接管信息。传入' ip:port' 字符串或`ChromiumDriver`时接管浏览器;传入`DriverOptions`时按配置启动浏览器;为`None`时使用配置文件配置启动浏览器 |
|
||||
| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
|
||||
| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
|
||||
|
||||
## 📍 `SessionPage`
|
||||
|
||||
`SessionPage`对象纯粹用于收发数据包,不能切换模式,产生的元素对象为`SessionElement`。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| -------------------- | ----------------------------- | ------ | --------------------------------------------------------------- |
|
||||
| `session_or_options` | `Session`<br>`SessionOptions` | `None` | 传入`Session`对象时使用该对象收发数据包;传入`SessionOptions`对象时用该配置创建`Session`对象 |
|
||||
| `timeout` | `float` | `None` | 连接超时时间,为`None`则从配置文件中读取 |
|
||||
|
||||
## 📍 `WebPage`
|
||||
|
||||
`WebPage`对象封装了常用的网页操作,并实现在浏览器和 requests 两种模式之间的切换。
|
||||
|
||||
| 初始化参数 | 类型 | 默认值 | 说明 |
|
||||
| -------------------- | --------------------------------------------- | ------ | ---------------------------------------------------------------- |
|
||||
| `mode` | `str` | `'d'` | 启动时的模式,只能传入`'d'`或`'s'` |
|
||||
| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
|
||||
| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
|
||||
| `driver_or_options` | `ChromiumDriver`<br>`bool` | `None` | 浏览器控制对象或浏览器启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
|
||||
| `session_or_options` | `Session`<br>`SessionOptions`<br>`bool` | `None` | 收发数据包对象或`Session`启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
|
||||
|
||||
**◽ 说明:**
|
||||
|
||||
`driver_or_options`和`session_or_options`传入`ChromiumDriver`和`Session`对象时,可在多个页面对象间传递控制权。
|
@ -1,176 +0,0 @@
|
||||
本节介绍如何访问网页。
|
||||
|
||||
# ✔️ 浏览器访问网页
|
||||
|
||||
`ChromiumPage`和`WebPage`的 d 模式用于控制浏览器,使用`get()`方法访问网页。
|
||||
|
||||
## 📍 `get()`方法
|
||||
|
||||
该方法用于跳转到一个网址。
|
||||
当连接失败时,程序默认重试 3 次,每次间隔 2 秒,可以通过参数设置重试次数和间隔。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:-------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 无 | 目标url |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `float` | `None` | 加载超时时间(秒) |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
**示例:**
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
## 📍 设置超时时间和重试参数
|
||||
|
||||
网络不稳定时访问页面不一定成功,`get()`方法内置了超时和重试功能。通过`retry`、`interval`、`timeout`三个参数进行设置。
|
||||
其中,如不指定`timeout`参数,该参数会使用`WebPage`的`timeouts`属性的`page_load`参数中的值。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
page.get('https://www.163.com', retry=1, interval=1, timeout=1.5)
|
||||
```
|
||||
|
||||
## 📍 设置加载策略
|
||||
|
||||
通过设置`WebPage`对象的`page_load_strategy`属性,可设置页面停止加载的时机。页面加载时,在到达超时时间,或达到设定的状态,就会停止,可有效节省采集时间。有以下三种模式:
|
||||
|
||||
- `'normal'`:常规模式,会等待页面加载完毕。
|
||||
|
||||
- `'eager'`:加载完 DOM 即停止加载。
|
||||
|
||||
- `'none'`:完成连接即停止加载。
|
||||
|
||||
默认设置为`'normal'`。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
page.set_page_load_strategy()
|
||||
```
|
||||
|
||||
# ✔️ 数据包访问网页
|
||||
|
||||
`SessionPage`和`WebPage`的 s 模式基于 requests,因此可使用 requests 内置的所有请求方式,包括`get()`、`post()`、`head()`、`options()`、`put()`、`patch()`、`delete()`
|
||||
。不过本库目前只对`get()`和`post()`做了封装和优化,其余方式可通过调用页面对象内置的`Session`对象调用。
|
||||
|
||||
## 📍 `get()`方法
|
||||
|
||||
`get()`方法使用语法与 requests 的`get()`方法一致,在此基础上增加了重试设置参数。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:-------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 无 | 目标url |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `float` | `None` | 加载超时时间(秒) |
|
||||
| `**kwargs` | - | `None` | 连接所需其它参数,具体见 requests 用法 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
`**kwargs`参数与 requests 中该参数使用方法一致,但有一个特点,如果该参数中设置了某一项(如`headers`),该项中的每个项会覆盖从配置中读取的同名项,而不会整个覆盖。
|
||||
就是说,如果想继续使用配置中的`headers`信息,而只想修改其中一项,只需要传入该项的值即可。这样可以简化代码逻辑。
|
||||
与 requests 不一样,`get()`方法不返回`Response`对象以获取结果,处理返回结果的方式详见后面章节。
|
||||
|
||||
实用功能:
|
||||
|
||||
- 程序会根据要访问的网址自动在`headers`中加入`Host`和`Referer`项
|
||||
- 程序会自动从返回内容中确定编码,一般情况无须手动设置
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage('s')
|
||||
|
||||
url = 'https://www.baidu.com'
|
||||
headers = {'referer': 'gitee.com'}
|
||||
cookies = {'name': 'value'}
|
||||
proxies = {'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
|
||||
page.get(url, headers=headers, cookies=cookies, proxies=proxies)
|
||||
```
|
||||
|
||||
?> s 模式访问时默认设置`redirect`参数为`False`,即访问重定向链接时须手动处理。
|
||||
|
||||
## 📍 `post()`方法
|
||||
|
||||
此方法是用 post 方式请求页面。用法与`get()`一致。调用时,`WebPage`对象会自动切换到 s 模式。
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|:-------------:|:---------------:|:-------:| --------------------------- |
|
||||
| `url` | `str` | 无 | 目标url |
|
||||
| `data` | `dict`<br>`str` | `None` | 提交的数据 |
|
||||
| `json` | `dict`<br>`str` | `None` | 提交的数据 |
|
||||
| `show_errmsg` | `bool` | `False` | 连接出错时是否显示和抛出异常 |
|
||||
| `retry` | `int` | `None` | 重试次数,为`None`时使用页面参数,默认 3 |
|
||||
| `interval` | `float` | `None` | 重试间隔(秒),为`None`时使用页面参数,默认 2 |
|
||||
| `timeout` | `float` | `None` | 加载超时时间(秒) |
|
||||
| `**kwargs` | - | `None` | 连接所需其它参数,具体见 requests 用法 |
|
||||
|
||||
| 返回类型 | 说明 |
|
||||
|:------:| ----- |
|
||||
| `bool` | 否连接成功 |
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage('s')
|
||||
data = {'username': 'xxxxx', 'pwd': 'xxxxx'}
|
||||
|
||||
page.post('http://example.com', data=data)
|
||||
# 或
|
||||
page.post('http://example.com', json=data)
|
||||
```
|
||||
|
||||
`data`参数和`json`参数都可接收`str`和`dict`格式数据,即有以下 4 种传递数据的方式:
|
||||
|
||||
```python
|
||||
# 向 data 参数传入字符串
|
||||
page.post(url, data='abc=123')
|
||||
|
||||
# 向 data 参数传入字典
|
||||
page.post(url, data={'abc': '123'})
|
||||
|
||||
# 向 json 参数传入字符串
|
||||
page.post(url, json='abc=123')
|
||||
|
||||
# 向 json 参数传入字典
|
||||
page.post(url, json={'abc': '123'})
|
||||
```
|
||||
|
||||
具体使用哪种,按服务器要求而定。
|
||||
|
||||
## 📍 其它请求方式
|
||||
|
||||
本库只针对常用的 get 和 post 方式作了优化,但也可以通过提取页面对象内的`Session`对象以原生 requests 代码方式执行其它请求方式。当然,它们工作在 s 模式。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage('s')
|
||||
# 获取内置的 Session 对象
|
||||
session = page.session
|
||||
# 以 head 方式发送请求
|
||||
response = session.head('https://www.baidu.com')
|
||||
print(response.headers)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```shell
|
||||
{'Accept-Ranges': 'bytes', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Length': '277', 'Content-Type': 'text/html', 'Date': 'Tue, 04 Jan 2022 06:49:18 GMT', 'Etag': '"575e1f72-115"', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:26 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18'}
|
||||
```
|
@ -1,832 +0,0 @@
|
||||
本节介绍如何获取元素对象。可以从页面中查找元素,也可以在元素中查找子元素。
|
||||
|
||||
无论是数据采集还是页面自动化,定位元素都是重中之重的的技能,浏览器开发者工具虽然可以直接复制绝对 xpath 或 css 路径,但这样做一来代码繁琐,可读性低,二来难以应付动态变化的页面。
|
||||
本库提供一套简洁易用的语法,用于快速定位元素,并且内置等待功能、支持链式查找,减少了代码的复杂性。
|
||||
|
||||
定位元素大致分为三种方法:
|
||||
|
||||
- 在页面或元素内查找子元素
|
||||
- 根据 DOM 结构相对定位
|
||||
- 根据页面布局位置相对定位
|
||||
|
||||
浏览器的元素还有专门用于处理 shadow dom 的`shadow_root`属性。获取到的元素可继续用这些方法获取后代元素,使用方法和普通元素一致。
|
||||
|
||||
# ✔️ 示例
|
||||
|
||||
先看一些示例,后面在详细讲解用法。
|
||||
|
||||
## 📍 简单示例
|
||||
|
||||
假设有这样一个页面:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<div id="one">
|
||||
<p class="p_cls" name="row1">第一行</p>
|
||||
<p class="p_cls" name="row2">第二行</p>
|
||||
<p class="p_cls">第三行</p>
|
||||
</div>
|
||||
<div id="two">
|
||||
第二个div
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
我们用页面对象去获取其中的元素:
|
||||
|
||||
```python
|
||||
# 获取 id 为 one 的元素
|
||||
div1 = page.ele('#one')
|
||||
|
||||
# 获取 div1 元素内所有 p 元素组成的列表
|
||||
p_eles = div1.eles('tag:p')
|
||||
|
||||
# 获取 name 属性为 row1 的元素
|
||||
p1 = page.ele('@name=row1')
|
||||
|
||||
# 获取 name 属性为 row2 且包含“第二”文本的 p 元素
|
||||
p_ele = page.ele('tag:p@@text():第二@@name=row2')
|
||||
|
||||
# 获取包含“第二个div”文本的元素
|
||||
div2 = page.ele('第二个div')
|
||||
|
||||
# 用 xpath 查找
|
||||
div2 = page.ele('xpath://div[@id="tow"]')
|
||||
|
||||
# 从第一行元素用相对定位获取第三行元素
|
||||
p3 = p1.next(2)
|
||||
|
||||
# 获取 p1 元素的父元素
|
||||
parent = p1.parent()
|
||||
|
||||
# 获取 p1 后面的第一个 div 元素
|
||||
div2 = p1.after(1, 'tag:div')
|
||||
```
|
||||
|
||||
## 📍 实际示例
|
||||
|
||||
复制此代码可直接运行查看结果。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage('s')
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取包含“全部推荐项目”文本的 ul 元素
|
||||
ul_ele = page.ele('tag:ul@@text():全部推荐项目')
|
||||
|
||||
# 获取该 ul 元素下所有 a 元素
|
||||
titles = ul_ele.eles('tag:a')
|
||||
|
||||
# 遍历列表,打印每个 a 元素的文本
|
||||
for i in titles:
|
||||
print(i.text)
|
||||
|
||||
"""
|
||||
输出:
|
||||
全部推荐项目
|
||||
前沿技术
|
||||
智能硬件
|
||||
IOT/物联网/边缘计算
|
||||
车载应用
|
||||
……
|
||||
"""
|
||||
```
|
||||
|
||||
# ✔️ 查找元素方法
|
||||
|
||||
## 📍 查找单个元素
|
||||
|
||||
查找单个元素使用`ele()`方法。
|
||||
|
||||
页面对象和元素对象都拥有此方法,用于查找第一个匹配条件的元素。
|
||||
d 模式下返回`ChromiumElement`对象,s 模式下返回`SessionElement`对象,没有找到返回`None`。
|
||||
在元素下查找子元素时,还可以用 xpath 获取元素属性,直接返回属性文本。
|
||||
页面对象和元素对象的`ele()`方法参数名称稍有不同,但用法一样。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_str`(元素对象):元素的定位信息,可以是 loc 元组,或查询字符串
|
||||
- `loc_or_ele`(页面对象):元素的定位信息,可以是元素对象,loc 元组,或查询字符串
|
||||
- `timeout`:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
|
||||
|
||||
**返回:** s 模式下返回`SessionElement`,d 模式下返回`ChromiumElement`;或用 xpath 获取到的属性值
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
|
||||
# 在页面内查找元素
|
||||
ele1 = page.ele('search text')
|
||||
|
||||
# 在元素内查找后代元素
|
||||
ele2 = ele1.ele('search text')
|
||||
|
||||
# 使用 xpath 获取后代中第一个 div 元素的 class 属性(元素内查找可用)
|
||||
ele_class = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
## 📍 查找多个元素
|
||||
|
||||
查找多个元素使用`eles()`方法。
|
||||
|
||||
此方法与`ele()`相似,但返回的是匹配到的所有元素组成的列表,用 xpath 获取元素属性时,返回属性文本组成的列表。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_str`:元素的定位信息,可以是 loc 元组,或查询字符串
|
||||
- `timeout`:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
|
||||
|
||||
**返回:** s 模式下返回`SessionElement`组成的列表,d 模式下返回`ChromiumElement`组成的列表;或用 xpath 获取到的属性值组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele 元素内的所有 p 元素
|
||||
p_eles = ele.eles('tag:p')
|
||||
# 打印第一个 p 元素
|
||||
print(p_eles[0])
|
||||
```
|
||||
|
||||
## 📍 查找单个静态元素
|
||||
|
||||
静态元素即 s 模式的`SessionElement`元素对象,是纯文本构造的,因此用它处理速度非常快速。对于复杂的页面,要在成百上千个元素中采集数据时,转换为静态元素可把速度提升几个数量级。作者曾在采集的时候,用同一套逻辑,仅仅把元素转换为静态,就把一个要 30 秒才采集 完成的页面,加速到零点几秒完成。
|
||||
我们甚至可以把整个页面转换为静态元素,再在其中提取信息。
|
||||
当然,这种元素不能进行点击等交互。
|
||||
s 模式下,所有元素本身就是静态元素,d 模式下,用`s_ele()`可在把查找到的动态元素转换为静态元素输出,或者获取元素或页面本身的静态元素副本。
|
||||
|
||||
`s_ele()`方法
|
||||
|
||||
页面对象和元素对象都拥有此方法,用于查找第一个匹配条件的元素,获取其静态版本。
|
||||
|
||||
页面对象和元素对象的`s_ele()`方法参数名称稍有不同,但用法一样。
|
||||
|
||||
此方法用于在一个元素下查找后代元素,以`SessionElement`形式返回结果(xpath 获取属性值时依然是返回`str`),也可以直接将一个元素或页面转换为`SessionElement`版本。
|
||||
|
||||
这是为了 d 模式处理速度的提升,当爬取复杂页面信息而且不须要和元素进行交互时,生成整个页面或者主要容器元素的`SessionElement`,再在其中获取信息,可以将速度提升几个数量级。
|
||||
|
||||
s 模式下这个方法和`ele()`是一样的。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_str`(元素对象):元素的定位信息,可以是 loc 元组,或查询字符串。为`None`时直接返回当前元素的`SessionElemnet`版本
|
||||
- `loc_or_ele`(页面对象):元素的定位信息,可以是 loc 元组,或查询字符串。为`None`时直接返回当前页面的 `SessionElemnet`版本
|
||||
|
||||
**返回:**`SessionElement`,或用 xpath 获取到的属性值
|
||||
|
||||
!>**注意:**<br>页面对象和元素对象的`s_ele()`方法不能搜索到在 frame 里的元素,页面对象的静态版本也不能搜索 frame 里的元素。要使用 frame 里元素的静态版本,可先获取该元素,再转换。而使用`ChromiumFrame`对象,则可以直接用`s_ele()`查找元素,这在后面章节再讲述。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
p = WebPage()
|
||||
|
||||
# 在页面中查找元素,获取其静态版本
|
||||
ele1 = page.s_ele('search text')
|
||||
|
||||
# 在动态元素中查找元素,获取其静态版本
|
||||
ele = page.ele('search text')
|
||||
ele2 = ele.s_ele()
|
||||
|
||||
# 获取页面元素的静态副本(不传入参数)
|
||||
s_page = page.s_ele()
|
||||
|
||||
# 获取动态元素的静态副本
|
||||
s_ele = ele.s_ele()
|
||||
|
||||
# 在静态副本中查询下级元素(因为已经是静态元素,用ele()查找结果也是静态)
|
||||
ele3 = s_page.ele('search text')
|
||||
ele4 = s_ele.ele('search text')
|
||||
```
|
||||
|
||||
## 📍 查找多个静态元素
|
||||
|
||||
查找多个静态元素使用`s_eles()`方法。
|
||||
|
||||
此方法与`s_ele()`相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_str`:元素的定位信息,可以是 loc 元组,或查询字符串(必填)
|
||||
|
||||
**返回:**`SessionElement`组成的列表,或用 xpath 获取到的属性值组成的列表
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
p = WebPage()
|
||||
for ele in p.s_eles('search text'):
|
||||
print(ele.text)
|
||||
```
|
||||
|
||||
## 📍 获取当前焦点元素
|
||||
|
||||
使用方法`active_ele()`获取页面上焦点所在元素,为 d 模式独有。
|
||||
|
||||
```python
|
||||
ele = page.active_ele
|
||||
```
|
||||
|
||||
## 📍 获取 shadow_root
|
||||
|
||||
d 模式元素如果包含 shadow_root,可使用`shadow_root`属性获取。
|
||||
该属性返回的是一个`ChromiumShadowRootElement`对象,用法与`ChromiumElement`相似。也能使用各种元素查找方式,返回内部元素或相对位置元素,返回 `ChromiumElement`元素。返回的`ChromiumElement`和普通的没有区别。
|
||||
|
||||
```python
|
||||
# 获取一个元素下是 shadow root
|
||||
shadow_ele = ele.shadow_root
|
||||
# 获取该 shadow root 下的一个元素
|
||||
ele1 = shadow_ele.ele('search text')
|
||||
# 点击获取到的元素
|
||||
ele1.click()
|
||||
```
|
||||
|
||||
# ✔️ 查找语法
|
||||
|
||||
我们使用一套简洁高效的语法去定位元素,大大简化了定位元素的代码量,增强了功能,也兼容 css selector、xpath、selenium 原生的 loc 元组(s 模式也能用)。d 模式和 s
|
||||
模式定位元素的语法是完全一样的,便于模式切换时平滑过渡。
|
||||
|
||||
**匹配模式** 指字符串是否完全匹配,有以下两种:
|
||||
|
||||
## 📍 精确匹配符 `=`
|
||||
|
||||
表示精确匹配,匹配完全符合的文本或属性。
|
||||
|
||||
## 📍 模糊匹配符 `:`
|
||||
|
||||
表示模糊匹配,匹配含有某个字符串的文本或属性。
|
||||
|
||||
**关键字** 是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
|
||||
|
||||
## 📍 id 匹配符 `#`
|
||||
|
||||
表示`id`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
|
||||
|
||||
```python
|
||||
# 在页面中查找 id 属性为 ele_id 的元素
|
||||
ele1 = page.ele('#ele_id')
|
||||
|
||||
# 在 ele1 元素内查找 id 属性包含 ele_id 文本的元素
|
||||
ele2 = ele1.ele('#:ele_id')
|
||||
```
|
||||
|
||||
## 📍 class 匹配符 `.`
|
||||
|
||||
表示`class`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
|
||||
|
||||
```python
|
||||
# 查找 class 属性为 ele_class 的元素
|
||||
ele2 = ele1.ele('.ele_class')
|
||||
|
||||
# 查找 class 属性包含 ele_class 文本的元素
|
||||
ele2 = ele1.ele('.:ele_class')
|
||||
```
|
||||
|
||||
## 📍 单属性匹配符 `@`
|
||||
|
||||
表示某个属性,只匹配一个属性。
|
||||
`@`关键字只有一个简单功能,就是匹配`@`后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在`@`或`@@`,也作为要匹配的内容对待。
|
||||
|
||||
!> **注意:**
|
||||
如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
|
||||
|
||||
```python
|
||||
# 查找 name 属性为 ele_name 的元素
|
||||
ele2 = ele1.ele('@name=ele_name')
|
||||
|
||||
# 查找 name 属性包含 ele_name 文本的元素
|
||||
ele2 = ele1.ele('@name:ele_name')
|
||||
|
||||
# 查找有 name 属性的元素
|
||||
ele2 = ele1.ele('@name')
|
||||
|
||||
# 查找没有任何属性的元素
|
||||
ele2 = ele1.ele('@')
|
||||
|
||||
# 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理
|
||||
ele2 = ele1.ele('@email=abc@def.com')
|
||||
|
||||
# 属性中有特殊字符的情形,匹配abc@def属性等于v的元素
|
||||
ele2 = ele1.ele('css:div[abc\@def="v"]')
|
||||
```
|
||||
|
||||
## 📍 多属性匹配符 `@@`
|
||||
|
||||
表示某个属性,多属性匹配时使用,个数不限。还能匹配要忽略的元素,匹配文本时也和`@`不一样。
|
||||
`@@`后跟 - 时,表示 not。如:
|
||||
|
||||
- `@@-name`表示匹配没有`name`属性的元素
|
||||
|
||||
- `@@-name=ele_name`表示匹配`name`属性不为`ele_name`的元素
|
||||
|
||||
如有以下情况,不能使用此方式,须改用 xpath 的方式:
|
||||
|
||||
- 匹配文本或属性中出现`@@`
|
||||
|
||||
- 属性名本身以`-`开头
|
||||
|
||||
!> **注意:**:<br>如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
|
||||
|
||||
```python
|
||||
# 查找 name 属性为 name 且 class 属性包含 cls 文本的元素
|
||||
ele2 = ele1.ele('@@name=name@@class:cls')
|
||||
|
||||
# 查找没有 class 属性的元素
|
||||
ele2 = ele1.ele('@@-class')
|
||||
|
||||
# 查找 name 属性不包含 ele_name 的元素
|
||||
ele2 = ele1.ele('@@-name:ele_name')
|
||||
```
|
||||
|
||||
## 📍 文本匹配符 `text`
|
||||
|
||||
要匹配的文本,查询字符串如开头没有任何关键字,也表示根据传入的文本作模糊查找。
|
||||
如果元素内有多个直接的文本节点,精确查找时可匹配所有文本节点拼成的字符串,模糊查找时可匹配每个文本节点。
|
||||
|
||||
```python
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('text=some text')
|
||||
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('text:some text')
|
||||
|
||||
# 与上一行一致
|
||||
ele2 = ele1.ele('some text')
|
||||
```
|
||||
|
||||
?> **Tips:** <br>若要查找的文本包含`text:` ,可下面这样写,即第一个`text:` 为关键字,第二个是要查找的内容:
|
||||
|
||||
```python
|
||||
ele2 = page.ele('text:text:')
|
||||
```
|
||||
|
||||
## 📍 文本匹配符 `text()`
|
||||
|
||||
作为查找属性时使用的文本关键字,必须与`@`或`@@`配合使用。
|
||||
|
||||
```python
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('@text()=some text')
|
||||
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('@text():some text')
|
||||
|
||||
# 查找文本为 some text 且 class 属性为 cls 的元素
|
||||
ele2 = ele1.ele('@@text()=some text@@class=cls')
|
||||
|
||||
# 查找文本为 some text 且没有任何属性的元素(因第一个 @@ 后为空)
|
||||
ele2 = ele1.ele('@@@@text():some text')
|
||||
|
||||
# 查找直接子文本包含 some text 字符串的元素,和 text 关键字没有区别
|
||||
ele = page.ele('@text():some text')
|
||||
ele = page.ele('text:some text')
|
||||
|
||||
# 查找元素内部包含 some text 字符串的元素
|
||||
ele = page.ele('@@text():some text')
|
||||
```
|
||||
|
||||
须要注意的是,`'text=xxxx'`与`'@text()=xxxx'`使用上是有细微差别的。
|
||||
|
||||
`text=`表示在元素的直接子文本节点中匹配,`@text()=`会忽略一些文本标签,在整个元素的内容里匹配。
|
||||
|
||||
## 📍 类型匹配符 `tag`
|
||||
|
||||
表示元素的标签,只在语句最前面且单独使用时生效,可与`@`或`@@`配合使用。`tag:`与`tag=`效果一致。
|
||||
|
||||
```python
|
||||
# 定位 div 元素
|
||||
ele2 = ele1.ele('tag:div')
|
||||
|
||||
# 定位 class 属性为 cls 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@class=cls')
|
||||
|
||||
# 定位文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text()=text')
|
||||
|
||||
# 定位 class 属性为 cls 且文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@class=cls@@text()=text')
|
||||
|
||||
# 查找直接文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text():text')
|
||||
|
||||
# 查找内部文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@text():text')
|
||||
```
|
||||
|
||||
?> **Tips:** <br>注意, `tag:div@text():text` 和 `tag:div@@text():text` 是有区别的,前者只在`div`的直接文本节点搜索,后者搜索`div`的整个内部。
|
||||
|
||||
## 📍 css selector 匹配符 `css`
|
||||
|
||||
表示用 css selector 方式查找元素。`css:`与`css=`效果一致。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('css:.div')
|
||||
|
||||
# 查找 div 子元素元素,这个写法是本库特有,原生不支持
|
||||
ele2 = ele1.ele('css:>div')
|
||||
```
|
||||
|
||||
## 📍 xpath 匹配符 `xpath`
|
||||
|
||||
表示用 xpath 方式查找元素。`xpath:`与`xpath=`效果一致。
|
||||
该方法支持完整的 xpath 语法,能使用 xpath 直接获取元素属性,selenium 不支持这种用法。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('xpath:.//div')
|
||||
|
||||
# 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
|
||||
ele2 = ele1.ele('xpath://div')
|
||||
|
||||
# 获取 div 元素的 class 属性,返回字符串
|
||||
txt = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
?> **Tips:** <br>查找元素的后代时,selenium 原生代码要求 xpath 前面必须加`.`,否则会变成在全个页面中查找。作者觉得这个设计是画蛇添足,既然已经通过元素查找了,自然应该只查找这个元素内部的元素。所以,用 xpath 在元素下查找时,最前面`//`或`/`前面的`.`可以省略。
|
||||
|
||||
## 📍 selenium 的 loc 元组
|
||||
|
||||
查找方法能直接接收 selenium 原生定位元组进行查找,s 模式下也支持这种写法。
|
||||
|
||||
```python
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
# 查找 id 为 ele_id 的元素
|
||||
loc1 = (By.ID, 'ele_id')
|
||||
ele = page.ele(loc1)
|
||||
|
||||
# 按 xpath 查找
|
||||
loc2 = (By.XPATH, '//div[@class="ele_class"]')
|
||||
ele = page.ele(loc2)
|
||||
```
|
||||
|
||||
# ✔️ 等待
|
||||
|
||||
## 📍 等待元素加载
|
||||
|
||||
由于网络的不稳定性、js 运行时间的不确定性等因素,经常须要等待元素加载到 DOM 中才能使用。
|
||||
|
||||
d 模式下所有查找元素操作都自带等待,时间默认跟随元素所在页面`timeout`属性(默认 10 秒),也可以在每次查找时单独设置,单独设置的等待时间不会改变页面原来设置。
|
||||
|
||||
```python
|
||||
# 页面初始化时设置查找元素超时时间为 15 秒
|
||||
page = WebPage(timeout=15)
|
||||
# 设置查找元素超时时间为 5 秒
|
||||
page.timeout = 5
|
||||
|
||||
# 使用页面超时时间来查找元素(5 秒)
|
||||
ele1 = page.ele('search text')
|
||||
# 为这次查找页面独立设置等待时间(1 秒)
|
||||
ele1 = page.ele('search text', timeout=1)
|
||||
# 查找后代元素,使用页面超时时间(5 秒)
|
||||
ele2 = ele1.ele('search text')
|
||||
# 查找后代元素,使用单独设置的超时时间(1 秒)
|
||||
ele2 = ele1.ele('some text', timeout=1)
|
||||
```
|
||||
|
||||
## 📍 等待元素状态改变
|
||||
|
||||
有时候我们须要等待元素到达某种状态,如显示、隐藏、删除。页面对象和元素对象都内置了`wait_ele()`方法,用于等待元素状态变化。
|
||||
|
||||
该方法可接收现成的`ChromiumElement`对象,或定位符,默认等待时间为页面对象的`timeout`值,也可以单独设定。
|
||||
|
||||
`wait_ele()`方法
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_ele`:要等待的元素,可以是元素或定位符
|
||||
- `timeout`:等待超时时间,默认使用页面超时时间
|
||||
|
||||
**方法:**
|
||||
|
||||
| 方法 | 参数 | 功能 |
|
||||
| ----------- | --- | ------------ |
|
||||
| `display()` | 无 | 等待元素从 DOM 显示 |
|
||||
| `hidden()` | 无 | 等待元素从 DOM 隐藏 |
|
||||
| `delete()` | 无 | 等待元素从 DOM 删除 |
|
||||
|
||||
**返回:** 这些方法返回布尔值,代表是否等待成功。
|
||||
|
||||
```python
|
||||
# 等待 id 为 div1 的元素显示,超时使用页面设置
|
||||
page.wait_ele('#div1').display()
|
||||
|
||||
# 等待 id 为 div1 的元素被删除(使用 loc 元组),设置超时3秒
|
||||
ele.wait_ele('#div1', timeout=3).delete()
|
||||
|
||||
# 等待已获取到的元素被隐藏
|
||||
ele2 = ele1.ele('#div1')
|
||||
ele1.wait_ele(ele2).hidden()
|
||||
```
|
||||
|
||||
# ✔️ 相对定位
|
||||
|
||||
以下方法可以以某元素为基准,在 DOM 中按照条件获取其兄弟元素、祖先元素、文档前后元素。
|
||||
除获取元素外,还能通过 xpath 获取任意节点内容,如文本节点、注释节点。这在处理元素和文本节点混排的时候非常有用。
|
||||
|
||||
## 📍 获取父级元素
|
||||
|
||||
`parent()`方法获取当前元素某一级父元素,可指定筛选条件或层数。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `level_or_loc`:第几级父元素,或定位符
|
||||
|
||||
**返回:** 某层父级元素
|
||||
|
||||
```python
|
||||
# 获取 ele1 的第二层父元素
|
||||
ele2 = ele1.parent(2)
|
||||
|
||||
# 获取 ele1 父元素中 id 为 id1 的元素
|
||||
ele2 = ele1.parent('#id1')
|
||||
```
|
||||
|
||||
## 📍 获取后面单个兄弟元素
|
||||
|
||||
`next()`方法返回当前元素后面的某一个同级元素,可指定筛选条件和第几个。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `index`:查询结果中的第几个
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素后面某个兄弟元素或节点文本
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第一个兄弟元素
|
||||
ele2 = ele1.next()
|
||||
|
||||
# 获取 ele1 后面第 3 个兄弟元素
|
||||
ele2 = ele1.next(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.next('tag:div', 3)
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.next('xpath:text()', 1)
|
||||
```
|
||||
|
||||
## 📍 获取后面多个兄弟元素
|
||||
|
||||
`nexts()`方法返回当前元素后面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素前面符合条件的兄弟元素或节点文本组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面所有兄弟元素
|
||||
eles = ele1.nexts()
|
||||
|
||||
# 获取 ele1 后面所有 div 兄弟元素
|
||||
divs = ele1.nexts('tag:div')
|
||||
|
||||
# 获取 ele1 后面的所有文本节点
|
||||
txts = ele1.nexts('xpath:text()')
|
||||
```
|
||||
|
||||
## 📍 获取前面单个兄弟元素
|
||||
|
||||
`prev()`方法返回当前元素前面的某一个同级元素,可指定筛选条件和第几个。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `index`:查询结果中的第几个
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素前面某个兄弟元素或节点文本
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第一个兄弟元素
|
||||
ele2 = ele1.prev()
|
||||
|
||||
# 获取 ele1 前面第 3 个兄弟元素
|
||||
ele2 = ele1.prev(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.prev(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.prev(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
## 📍 获取前面多个兄弟元素
|
||||
|
||||
`prevs()`方法返回当前元素前面全部符合条件的同级元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素前面符合条件的兄弟元素或节点文本组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有兄弟元素
|
||||
eles = ele1.prevs()
|
||||
|
||||
# 获取 ele1 前面所有 div 兄弟元素
|
||||
divs = ele1.prevs('tag:div')
|
||||
```
|
||||
|
||||
## 📍 在后面文档中查找单个元素
|
||||
|
||||
`after()`方法返回当前元素后面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `index`:查询结果中的第几个
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素后面某个元素或节点
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第 3 个元素
|
||||
ele2 = ele1.after(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 元素
|
||||
ele2 = ele1.after('tag:div', 3)
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.after('xpath:text()', 1)
|
||||
```
|
||||
|
||||
## 📍 在后面文档中查找多个元素
|
||||
|
||||
`afters()`方法返回当前元素后面符合条件的全部元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素后面符合条件的元素或节点组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 后所有元素
|
||||
eles = ele1.afters()
|
||||
|
||||
# 获取 ele1 前面所有 div 元素
|
||||
divs = ele1.afters('tag:div')
|
||||
```
|
||||
|
||||
## 📍 在前面文档中查找单个元素
|
||||
|
||||
`before()`方法返回当前元素前面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `index`:查询结果中的第几个
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素前面某个元素或节点
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第 3 个元素
|
||||
ele2 = ele1.before(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 元素
|
||||
ele2 = ele1.before('tag:div', 3)
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.before('xpath:text()', 1)
|
||||
```
|
||||
|
||||
## 📍 在前面文档中查找多个元素
|
||||
|
||||
`befores()`方法返回当前元素前面全部符合条件的元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `filter_loc`:用于筛选元素的查询语法
|
||||
- `timeout`:查找元素的超时时间
|
||||
|
||||
**返回:** 本元素前面符合条件的元素或节点组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有元素
|
||||
eles = ele1.befores()
|
||||
|
||||
# 获取 ele1 前面所有 div 元素
|
||||
divs = ele1.befores('tag:div')
|
||||
```
|
||||
|
||||
# ✔️ 查找 frame 里的元素
|
||||
|
||||
## 📍 在页面下跨级查找
|
||||
|
||||
与 selenium 不同,本库可以直接查找 frame 里面的元素,而且无视层级,可以直接获取到多层 iframe 里的元素。无需切入切出,大大简化了程序逻辑,使用更便捷。
|
||||
|
||||
假设在页面中有个两级 iframe,其中有个元素`<div id='abc'></div>`,可以这样获取:
|
||||
|
||||
```python
|
||||
page = WebPage()
|
||||
ele = page('#abc')
|
||||
```
|
||||
|
||||
获取前后无须切入切出,也不影响获取页面上其它元素。如果用 selenium,要这样:
|
||||
|
||||
```python
|
||||
driver = webdriver.Chrome()
|
||||
driver.switch_to.frame(0)
|
||||
driver.switch_to.frame(0)
|
||||
ele = driver.find_element(By.ID, 'abc')
|
||||
driver.switch_to.default_content()
|
||||
```
|
||||
|
||||
显然比较繁琐,而且切入到 iframe 后无法对 iframe 外的元素进行操作。
|
||||
|
||||
!>**注意:**<br>跨级查找只是页面对象支持,元素对象不能直接查找内部 iframe 里的元素。
|
||||
|
||||
## 📍 在 iframe 元素下查找
|
||||
|
||||
本库把 iframe 看作一个特殊元素/页面对象看待,逻辑更清晰,还可以实现同时操作多个 iframe,而无须来回切换。查找元素外的更多功能详见介绍 iframe 的章节。
|
||||
|
||||
对于跨域名的 iframe,我们无法通过页面直接查找里面的元素,可以先获取到 iframe 元素,再在其下查找。当然,非跨域 iframe 也可以这样操作。
|
||||
|
||||
假设一个 iframe 的 id 为 `'iframe1'`,要在其中查找一个 id 为`'abc'`的元素:
|
||||
|
||||
```python
|
||||
page = WebPage()
|
||||
iframe = page('#iframe1')
|
||||
ele = iframe('#abc')
|
||||
```
|
||||
|
||||
这个 iframe 元素是一个页面对象,因此可以继续在其下进行跨 iframe 查找(相对这个 iframe 不跨域的)。
|
||||
|
||||
# ✔️ `ShadowRootElement`相关查找
|
||||
|
||||
本库把 shadow-root 也作为元素对象看待,是为`ChromiumShadowRootElement`对象。该对象可与普通元素一样查找下级元素和 DOM 内相对定位。
|
||||
对`ChromiumShadowRootElement`对象进行相对定位时,把它看作其父对象内部的第一个对象,其余定位逻辑与普通对象一致。
|
||||
|
||||
!> **注意:** <br>如果`ChromiumShadowRootElement`元素的下级元素中有其它`ChromiumShadowRootElement`元素,那这些下级`ChromiumShadowRootElement`
|
||||
元素内部是无法直接通过定位语句查找到的,只能先定位到其父元素,再用`shadow-root`属性获取。
|
||||
|
||||
```python
|
||||
# 获取一个 shadow-root 元素
|
||||
sr_ele = page.ele('#app').shadow_root
|
||||
|
||||
# 在该元素下查找下级元素
|
||||
ele1 = sr_ele.ele('tag:div')
|
||||
|
||||
# 用相对定位获取其它元素
|
||||
ele1 = sr_ele.parent(2)
|
||||
ele1 = sr_ele.next('tag:div', 1)
|
||||
ele1 = sr_ele.after('tag:div', 1)
|
||||
eles = sr_ele.nexts('tag:div')
|
||||
|
||||
# 定位下级元素中的 shadow+-root 元素
|
||||
sr_ele2 = sr_ele.ele('tag:div').shadow_root
|
||||
```
|
||||
|
||||
# ✔️ 简化写法
|
||||
|
||||
为进一步精简代码,对语法进行了精简
|
||||
|
||||
- 定位语法都有其简化形式。
|
||||
- 页面和元素对象都实现了`__call__()`方法,可直接调用。
|
||||
- 所有查找方法都支持链式操作
|
||||
|
||||
示例:
|
||||
|
||||
```python
|
||||
# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
eles = page('#table_id').eles('t:tr')
|
||||
|
||||
# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
ele2 = ele1('.cls1')('tx=text')
|
||||
|
||||
# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
ele2 = ele1.sr('.cls')
|
||||
|
||||
# 按xpath 查找元素
|
||||
ele2 = ele1('x://div[@class="ele_class"]')
|
||||
```
|
||||
|
||||
简化写法对应列表
|
||||
|
||||
| 原写法 | 简化写法 |
|
||||
|:-------------:|:------:|
|
||||
| `text` | `tx` |
|
||||
| `text()` | `tx()` |
|
||||
| `tag` | `t` |
|
||||
| `xpath` | `x` |
|
||||
| `css` | `c` |
|
||||
| `shadow_root` | `sr` |
|
||||
|
||||
# ✔️ Tips
|
||||
|
||||
- 从一个`ChromiumElement`元素获取到的`SessionElement`版本,依然能够使用相对定位方法定位祖先或兄弟元素。但如果元素在 frame 中,相对定位不能超越 frame 文档。
|
||||
- `SessionElement`和`SessionPage`的`ele()`和`eles()`方法也有`timeout`参数,但它是不生效的,仅用于保持与 d 模式元素书写一致,便于无差别的调用。
|
||||
- 定位语句内容与关键字重复时,请使用 xpath 或 css selector 代替。
|
@ -1,415 +0,0 @@
|
||||
获取到须要的页面元素后,可以使用元素对象获取元素的信息。
|
||||
|
||||
`WebPage`常用的元素对象有四种:
|
||||
|
||||
- `ChromiumElement`:浏览器一般元素
|
||||
|
||||
- `ChromiumShadowRootElement`:shadow-root 元素
|
||||
|
||||
- `ChromiumFrame`:专门用于操作`<iframe>`元素的对象
|
||||
|
||||
- `SessionElement`:s 模式的元素,或前 3 者转换而成的静态元素
|
||||
|
||||
前三者是 d 模式下通过浏览器页面元素生成,后者是 s 模式由静态文本生成。
|
||||
|
||||
`ChromiumElement`对象拥有`SessionElement`对象所有属性。
|
||||
|
||||
`ChromiumFrame`作为既是元素又是页面的存在,后面章节单独介绍。
|
||||
|
||||
# ✔️ 简单示例
|
||||
|
||||
以下示例可直接运行查看结果:
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage('s')
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取推荐目录下所有 a 元素
|
||||
li_eles = page('tag:ul@@text():全部推荐项目').eles('t:a')
|
||||
|
||||
for i in li_eles: # 遍历列表
|
||||
print(i.tag, i.text, i.attr('href')) # 获取并打印标签名、文本、href 属性
|
||||
|
||||
"""输出:
|
||||
a 全部推荐项目 https://gitee.com/explore/all
|
||||
a 前沿技术 https://gitee.com/explore/new-tech
|
||||
a 智能硬件 https://gitee.com/explore/hardware
|
||||
a IOT/物联网/边缘计算 https://gitee.com/explore/iot
|
||||
a 车载应用 https://gitee.com/explore/vehicle
|
||||
以下省略……
|
||||
"""
|
||||
```
|
||||
|
||||
# ✔️ `SessionElement`属性
|
||||
|
||||
假设`ele`为以下`div`元素的对象:
|
||||
|
||||
```html
|
||||
<div id="div1" class="divs">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
```
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回元素的`outerHTML`文本。
|
||||
|
||||
```python
|
||||
html = ele.html
|
||||
"""返回:
|
||||
<div id="div1" class="divs">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
"""
|
||||
```
|
||||
|
||||
## 📍 `inner_html`
|
||||
|
||||
此属性返回元素的`innerHTML`文本。
|
||||
|
||||
```python
|
||||
inner_html = ele.inner_html
|
||||
"""返回:
|
||||
Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
"""
|
||||
```
|
||||
|
||||
## 📍 `tag`
|
||||
|
||||
此属性返回元素的标签名。
|
||||
|
||||
```python
|
||||
tag = ele.tag
|
||||
# 返回:div
|
||||
```
|
||||
|
||||
## 📍 `text`
|
||||
|
||||
此属性返回元素内所有文本组合成的字符串。
|
||||
该字符串已格式化,即已转码,已去除多余换行符,符合人读取习惯,便于直接使用。无须重复写处理代码。
|
||||
|
||||
```python
|
||||
text = ele.text
|
||||
"""返回:
|
||||
Hello World!
|
||||
行元素
|
||||
"""
|
||||
```
|
||||
|
||||
## 📍 `raw_text`
|
||||
|
||||
此属性返回元素内原始文本。
|
||||
|
||||
```python
|
||||
text = ele.raw_text
|
||||
"""返回(注意保留了元素间的空格和换行):
|
||||
Hello World!
|
||||
行元素
|
||||
|
||||
|
||||
"""
|
||||
```
|
||||
|
||||
## 📍 `texts()`
|
||||
|
||||
此方法返回元素内所有**直接**子节点的文本,包括元素和文本节点。 它有一个参数`text_node_only`,为`True`时则只获取只返回不被包裹的文本节点。这个方法适用于获取文本节点和元素节点混排的情况。
|
||||
|
||||
参数:
|
||||
|
||||
- `text_node_only`:是否只返回文本节点
|
||||
|
||||
返回:文本列表
|
||||
|
||||
```python
|
||||
texts = ele.texts()
|
||||
print(e.texts())
|
||||
# 输出:['Hello World!', '行元素']
|
||||
|
||||
print(e.texts(text_node_only=True))
|
||||
# 输出:['Hello World!']
|
||||
```
|
||||
|
||||
## 📍 `comments`
|
||||
|
||||
此属性以列表形式返回元素内的注释。
|
||||
|
||||
```python
|
||||
comments = ele.comments
|
||||
# 返回:[<!--这是注释-->]
|
||||
```
|
||||
|
||||
## 📍 `attrs`
|
||||
|
||||
此属性以字典形式返回元素所有属性及值。
|
||||
|
||||
```python
|
||||
attrs = ele.attrs
|
||||
# 返回:{'id': 'div1', 'class': 'divs'}
|
||||
```
|
||||
|
||||
## 📍 `attr()`
|
||||
|
||||
此方法返回元素某个`attribute`属性值。它接收一个字符串参数`attr`,返回该属性值文本,无该属性时返回`None`。
|
||||
此属性返回的`src`、`href`属性为已补充完整的路径。`text`属性为已格式化文本。
|
||||
|
||||
参数:
|
||||
|
||||
- `attr`:属性名称
|
||||
|
||||
返回:属性值文本
|
||||
|
||||
```python
|
||||
ele_id = ele.attr('id')
|
||||
# 返回:div1
|
||||
```
|
||||
|
||||
## 📍 `link`
|
||||
|
||||
此方法返回元素的 href 属性或 src 属性,没有这两个属性则返回`None`。
|
||||
|
||||
```html
|
||||
<a href='http://www.baidu.com'>百度</a>
|
||||
```
|
||||
|
||||
假设`a_ele`为以上元素的对象:
|
||||
|
||||
```python
|
||||
link = a_ele.link
|
||||
# 返回:http://www.baidu.com
|
||||
```
|
||||
|
||||
## 📍 `page`
|
||||
|
||||
此属性返回元素所在的页面对象。由 html 文本直接生成的`SessionElement`的`page`属性为`None`。
|
||||
|
||||
```python
|
||||
page = ele.page
|
||||
```
|
||||
|
||||
## 📍 `xpath`
|
||||
|
||||
此属性返回当前元素在页面中 xpath 的绝对路径。
|
||||
|
||||
```python
|
||||
xpath = ele.xpath
|
||||
# 返回:/html/body/div
|
||||
```
|
||||
|
||||
## 📍 `css_path`
|
||||
|
||||
此属性返回当前元素在页面中 css selector 的绝对路径。
|
||||
|
||||
```python
|
||||
css = ele.css_path
|
||||
# 返回::nth-child(1)>:nth-child(1)>:nth-child(1)
|
||||
```
|
||||
|
||||
# ✔️ `ChromiumElement`属性
|
||||
|
||||
`ChromiumElement`对象拥有`SessionElement`对象上述所有属性,并因运行在浏览器中拥有更丰富的属性。
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
此属性以元组形式返回元素的大小。
|
||||
|
||||
```python
|
||||
size = ele.size
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
## 📍 `location`
|
||||
|
||||
此属性以元组形式返回元素**左上角**在**整个页面**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.location
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
## 📍 `client_location`
|
||||
|
||||
此属性以元组形式返回元素**左上角**在**当前视口**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.client_location
|
||||
# 返回:(50, 50)
|
||||
```
|
||||
|
||||
## 📍 `midpoint`
|
||||
|
||||
此属性以元组形式返回元素**中点**在**整个页面**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.midpoint
|
||||
# 返回:(55, 55)
|
||||
```
|
||||
|
||||
## 📍 `client_midpoint`
|
||||
|
||||
此属性以元组形式返回元素**中点**在**视口**中的坐标。
|
||||
|
||||
```python
|
||||
loc = ele.client_midpoint
|
||||
# 返回:(55, 55)
|
||||
```
|
||||
|
||||
## 📍 `pseudo_before`
|
||||
|
||||
此属性以文本形式返回当前元素的`::before`伪元素内容。
|
||||
|
||||
```python
|
||||
before_txt = ele.pseudo_before
|
||||
```
|
||||
|
||||
## 📍 `pseudo_after`
|
||||
|
||||
此属性以文本形式返回当前元素的`::after`伪元素内容。
|
||||
|
||||
```python
|
||||
after_txt = ele.pseudo_after
|
||||
```
|
||||
|
||||
## 📍 `style()`
|
||||
|
||||
该方法返回元素 css 样式属性值,可获取伪元素的属性。它有两个参数,`style`参数输入样式属性名称,`pseudo_ele`参数输入伪元素名称,省略则获取普通元素的 css 样式属性。
|
||||
|
||||
参数:
|
||||
|
||||
- `style`:样式名称
|
||||
- `pseudo_ele`:伪元素名称(如有)
|
||||
|
||||
返回:样式属性值
|
||||
|
||||
```python
|
||||
# 获取 css 属性的 color 值
|
||||
prop = ele.style('color')
|
||||
|
||||
# 获取 after 伪元素的内容
|
||||
prop = ele.style('content', 'after')
|
||||
```
|
||||
|
||||
## 📍 `prop()`
|
||||
|
||||
此方法返回`property`属性值。它接收一个字符串参数,返回该参数的属性值。
|
||||
|
||||
参数:
|
||||
|
||||
- `prop`:属性名称
|
||||
|
||||
返回:属性值
|
||||
|
||||
## 📍`is_in_viewport`
|
||||
|
||||
此属性以布尔值方式返回元素是否在视口中,以元素可以接受点击的点为判断。
|
||||
|
||||
## 📍`is_alive`
|
||||
|
||||
此属性以布尔值形式返回当前元素是否仍可用。用于判断 d 模式下是否因页面刷新而导致元素失效。
|
||||
|
||||
## 📍 `is_selected`
|
||||
|
||||
此属性以布尔值返回元素是否选中。
|
||||
|
||||
## 📍 `is_enabled`
|
||||
|
||||
此属性以布尔值返回元素是否可用。
|
||||
|
||||
## 📍 `is_displayed`
|
||||
|
||||
此属性以布尔值返回元素是否可见。
|
||||
|
||||
# ✔️ 保存和截图
|
||||
|
||||
保存功能是本库一个特色功能,可以直接读取浏览器缓存,无须依赖 gui 或重新下载就可以保存页面资源。
|
||||
|
||||
作为对比,selenium 无法自身实现图片另存,往往须要通过使用 gui 进行辅助,不仅效率和可靠性低,还占用键鼠资源。
|
||||
|
||||
## 📍 `get_src()`
|
||||
|
||||
此方法用于返回元素`src`属性所使用的资源。base64 的会转为`bytes`返回,其它的以`str`返回。无资源的返回`None`。
|
||||
|
||||
例如,可获取页面上图片字节数据,用于识别内容,或保存到文件。`<script>`标签也可获取 js 文本。
|
||||
|
||||
!> 无法获取 Blob 内容。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:** 资源内容字符串
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
src = img.get_src()
|
||||
```
|
||||
|
||||
## 📍 `save()`
|
||||
|
||||
此方法用于保存`get_src()`方法获取到的资源到文件。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `path`:文件保存路径,为`None`时保存到当前文件夹
|
||||
|
||||
- `rename`:文件名称,须包含后缀,为`None`时从资源url获取
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
img.save('D:\\img.png')
|
||||
```
|
||||
|
||||
## 📍 `get_screenshot()`
|
||||
|
||||
此方法用于对元素进行截图。若截图时元素在视口外,须 90 以上版本内核支持。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `path`:图片完整路径,后缀可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`
|
||||
|
||||
- `as_bytes`:是否已字节形式返回图片,可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`。为`True`时以`'png'`输出。生效时`path`参数无效。
|
||||
|
||||
**返回:** 图片完整路径或字节文本
|
||||
|
||||
```python
|
||||
img = page('tag:img')
|
||||
img.get_screenshot()
|
||||
bytes_str = img.get_screenshot(as_bytes='png') # 返回截图二进制文本
|
||||
```
|
||||
|
||||
# ✔️ `ChromiumShadowRootElement`属性
|
||||
|
||||
本库把 shadow dom 的`root`看作一个元素处理,可以获取属性,也可以执行其下级的查找,使用逻辑与`ChromiumElement`一致,但属性较之少,有如下这些:
|
||||
|
||||
## 📍 `tag`
|
||||
|
||||
此属性返回元素标签名,即`'shadow-root'`。
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回`shadow_root`的 html 文本,由`<shadow_root></shadow_root>` 标签包裹。
|
||||
|
||||
## 📍 `inner_html`
|
||||
|
||||
此属性返回`shadow_root`内部的 html 文本。
|
||||
|
||||
## 📍 `page`
|
||||
|
||||
此属性返回元素所在页面对象。
|
||||
|
||||
## 📍 `parent_ele`
|
||||
|
||||
此属性返回所依附的普通元素对象。
|
||||
|
||||
## 📍 `is_enabled`
|
||||
|
||||
与`ChromiumElement`一致。
|
||||
|
||||
## 📍 `is_alive`
|
||||
|
||||
与`ChromiumElement`一致。
|
@ -1,239 +0,0 @@
|
||||
页面对象共有以下几种:
|
||||
|
||||
- `WebPage`:可在 s 和 d 模式之间切换,整合两种模式
|
||||
|
||||
- `ChromiumPage`:单纯用于操作浏览器,工作于 d 模式
|
||||
|
||||
- `ChromiumTab`:浏览器标签页对象,用于支持同时操作个多标签页
|
||||
|
||||
- `ChromiumFrame`:`<iframe>`元素对象,专门用于操作该元素
|
||||
|
||||
- `SessionPage`:单纯用于收发数据包,工作于 s 模式
|
||||
|
||||
各种页面对象使用方法是一致的,以下用`WebPage`按两种模式介绍。d 模式包含 s模式所有属性。
|
||||
|
||||
`ChromiumTab`和`ChromiumFrame`具体用法将在后面章节单独介绍。
|
||||
|
||||
# ✔️ 运行状态信息
|
||||
|
||||
## 📍 `url`
|
||||
|
||||
此属性返回当前访问的 url,两种模式均支持。
|
||||
|
||||
## 📍 `address`
|
||||
|
||||
此属性返回当前对象控制的页面地址和端口,仅用于 d 模式。
|
||||
|
||||
```python
|
||||
print(page.address)
|
||||
# 输出:127.0.0.1:9222
|
||||
```
|
||||
|
||||
## 📍 `tab_id`
|
||||
|
||||
此属性返回当前标签页的 id,仅用于 d 模式。
|
||||
|
||||
## 📍 `mode`
|
||||
|
||||
此属性返回当前页面对象的模式,`'s'`或`'d'`。
|
||||
|
||||
## 📍 `process_id`
|
||||
|
||||
此属性返回浏览器进程 id,仅用于 d 模式。
|
||||
|
||||
## 📍 `is_loading`
|
||||
|
||||
此属性返回页面是否正在加载状态,仅用于 d 模式。
|
||||
|
||||
## 📍 `ready_state`
|
||||
|
||||
此属性返回页面当前加载状态,有 3 种:`'loading'`、`'interactive'`、`'complete'`,仅用于 d 模式。
|
||||
|
||||
## 📍 `url_available`
|
||||
|
||||
此属性以布尔值返回当前链接是否可用,两种模式均支持。
|
||||
|
||||
# ✔️ 窗口及页面信息
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
此属性以`tuple`返回页面尺寸,仅用于 d 模式。格式:(宽度, 高度)。
|
||||
|
||||
## 📍 `tabs_count`
|
||||
|
||||
此属性返回当前浏览器标签页数量,仅用于 d 模式。
|
||||
|
||||
## 📍 `tabs`
|
||||
|
||||
此属性以列表形式返回当前浏览器所有标签页 id,仅用于 d 模式。
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回当前页面 html 文本,两种模式均支持。
|
||||
|
||||
## 📍 `json`
|
||||
|
||||
此属性把请求内容解析成 json,两种模式均支持。
|
||||
比如请求接口时,返回内容是 json 格式,那就可以用这个属性获取。
|
||||
事实上,用`html`属性获取也是可以的,不过`html`属性没有对文本进行解析。
|
||||
|
||||
## 📍 `title`
|
||||
|
||||
此属性返回当前页面`title`文本,两种模式均支持。
|
||||
|
||||
# ✔️ 配置参数信息
|
||||
|
||||
## 📍 `timeout`
|
||||
|
||||
s 模式下,此属性代表网络请求超时时间。
|
||||
d 模式下,此属性为元素查找、点击、处理提示框等操作的超时时间。
|
||||
默认为 10,可对其赋值。
|
||||
|
||||
```python
|
||||
# 创建 MixPage 对象时指定
|
||||
page = WebPage(timeout=5)
|
||||
|
||||
# 修改 timeout
|
||||
page.timeout = 20
|
||||
```
|
||||
|
||||
## 📍 `timeouts`
|
||||
|
||||
此属性以字典方式返回三种超时时间,仅用于 d 模式。
|
||||
`'implicit'`用于元素查找、点击重试、输入文本重试、处理弹出框重试等;
|
||||
`'page_load'`用于等待页面加载;
|
||||
`'script'`用于等待脚本执行。
|
||||
|
||||
```python
|
||||
print(page.timeouts)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'implicit': 10, 'pageLoad': 30.0, 'script': 30.0}
|
||||
```
|
||||
|
||||
## 📍 `retry_times`
|
||||
|
||||
此属性为网络连接失败时的重试次数。默认为 3,可对其赋值,两种模式均支持。
|
||||
|
||||
```python
|
||||
# 修改重试次数
|
||||
page.retry_times = 5
|
||||
```
|
||||
|
||||
## 📍 `retry_interval`
|
||||
|
||||
此属性为网络连接失败时的重试等待间隔秒数。默认为 2,可对其赋值,两种模式均支持。
|
||||
|
||||
```python
|
||||
# 修改重试等待间隔时间
|
||||
page.retry_interval = 1.5
|
||||
```
|
||||
|
||||
## 📍 `page_load_strategy`
|
||||
|
||||
此属性返回页面加载策略,有 3 种:`'none'`、`'normal'`、`'eager'`,仅用于 d 模式。
|
||||
|
||||
# ✔️ cookies 和缓存信息
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
此属性以`dict`方式返回当前页面所使用的 cookies,两种模式均支持。
|
||||
|
||||
## 📍 `get_cookies()`
|
||||
|
||||
此方法获取 cookies 并以 cookie 组成的`list`形式返回,两种模式均支持。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `as_dict`:是否以字典方式返回,为`False`返回 cookie 组成的`list`
|
||||
- `all_domains`:是否返回所有域的 cookies,只有 s 模式下生效
|
||||
|
||||
**返回:** cookies 信息
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
p = WebPage('s')
|
||||
p.get('http://www.baidu.com')
|
||||
p.get('http://gitee.com')
|
||||
|
||||
for i in p.get_cookies(as_dict=False, all_domains=True):
|
||||
print(i)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'domain': '.baidu.com', 'domain_specified': True, ......}
|
||||
......
|
||||
{'domain': 'gitee.com', 'domain_specified': False, ......}
|
||||
......
|
||||
```
|
||||
|
||||
## 📍 `get_session_storage()`
|
||||
|
||||
此方法用于获取 sessionStorage 信息,可获取全部或单个项,仅用于 d 模式。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `item`:要获取的项,不设置则返回全部
|
||||
|
||||
**返回:** sessionStorage 一个或所有项内容
|
||||
|
||||
## 📍 `get_local_storage()`
|
||||
|
||||
此方法用于获取 localStorage 信息,可获取全部或单个项,仅用于 d 模式。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `item`:要获取的项,不设置则返回全部
|
||||
|
||||
**返回:** localStorage 一个或所有项内容
|
||||
|
||||
# ✔️ 内嵌对象
|
||||
|
||||
## 📍 `session`
|
||||
|
||||
此属性返回当前页面对象使用的`Session`对象,仅用于 s 模式。
|
||||
|
||||
## 📍 `response`
|
||||
|
||||
此属性为 s 模式请求网站后生成的`Response`对象,本库没实现的功能可直接获取此属性调用 requests 库的原生功能,仅用于 s 模式。
|
||||
|
||||
```python
|
||||
# 打印连接状态
|
||||
r = page.response
|
||||
print(r.status_code)
|
||||
```
|
||||
|
||||
## 📍 `driver`
|
||||
|
||||
此属性返回当前页面对象使用的`ChromiumDriver`对象,仅用于 d 模式。
|
||||
|
||||
# ✔️ 页面截图
|
||||
|
||||
## 📍 `get_screenshot()`
|
||||
|
||||
此方法用于对页面进行截图,可对整个网页、可见网页、指定范围截图。对可视范围外截图需要90以上版本浏览器支持,仅用于 d 模式。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `path`:保存图片的完整路径,后缀可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`
|
||||
|
||||
- `as_bytes`:是否已字节形式返回图片,可选`'jpg'`、`'jpeg'`、`'png'`、`'webp'`、`None`、`True`
|
||||
|
||||
- `full_page`:是否整页截图,为`True`截取整个网页,为`False`截取可视窗口
|
||||
|
||||
- `left_top`:截取范围左上角坐标
|
||||
|
||||
- `right_bottom`:截取范围右下角角坐标
|
||||
|
||||
**返回:** 图片完整路径或字节文本
|
||||
|
||||
```python
|
||||
# 对整页截图并保存
|
||||
page.get_screenshot(path='D:\\page.png', full_page=True)
|
||||
```
|
@ -1,544 +0,0 @@
|
||||
本节介绍`WebPage`对象可以使用的方法,有些方法是两种模式共有的,有些只有某种模式可以使用。当调用独有方法时,会自动切换到该模式。如调用`post()`方法时,会先切换到 s 模式,并同步登录信息。
|
||||
|
||||
# ✔️ 页面跳转
|
||||
|
||||
## 📍 `get()`
|
||||
|
||||
此方法用于跳转到一个 url,两种模式都支持,详细用法见“使用方法 -> 访问网页”章节。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `url`:目标 url
|
||||
- `show_errmsg`:是否显示和抛出异常,默认不抛出,连接错误会返回 `None`
|
||||
- `retry`:重试次数,与页面对象的设置一致,默认 3 次
|
||||
- `interval`:重试间隔(秒),与页面对象的设置一致,默认 2 秒
|
||||
- `timeout`:连接超时时间(秒)
|
||||
- `**kwargs`:s 模式用到的连接参数,具体见 requests 用法
|
||||
|
||||
**返回:**`bool`类型,表示是否连接成功
|
||||
|
||||
```python
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
## 📍 `post()`
|
||||
|
||||
此方法用于以 post 方式访问 url,仅 s 模式支持。具体用法见“使用方法 -> 访问网页”章节。
|
||||
|
||||
参数:
|
||||
|
||||
- `url`:目标 url
|
||||
- `data`:提交的数据,可以是`dict`或`str`类型
|
||||
- `json`:提交的数据,可以是`dict`或`str`类型
|
||||
- `show_errmsg`:是否显示和抛出异常,默认不抛出,连接错误会返回`None`
|
||||
- `retry`:重试次数,与页面对象的设置一致,默认 3 次
|
||||
- `interval`:重试间隔(秒),与页面对象的设置一致,默认 2 秒
|
||||
- `**kwargs`:连接参数,具体见 requests 用法
|
||||
|
||||
返回:**`bool`类型,表示是否连接成功
|
||||
|
||||
```python
|
||||
page.post('https://xxxxxx', data=data)
|
||||
```
|
||||
|
||||
## 📍 `back()`
|
||||
|
||||
此方法用于在浏览历史中后退若干步,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `steps`:后退步数
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.back(2) # 后退两个网页
|
||||
```
|
||||
|
||||
## 📍 `forward()`
|
||||
|
||||
此方法用于在浏览历史中前进若干步,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `steps`:前进步数
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.forward(2) # 前进两步
|
||||
```
|
||||
|
||||
## 📍 `refresh()`
|
||||
|
||||
此方法用于刷新当前页面,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `ignore_cache`:刷新时是否忽略缓存
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.refresh() # 刷新页面
|
||||
```
|
||||
|
||||
## 📍 `stop_loading()`
|
||||
|
||||
此方法用于强制当前页面加载,d 模式独有。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:`None`
|
||||
|
||||
## 📍 `wait_loading()`
|
||||
|
||||
此方法用于等待页面进入加载状态,d 模式独有。
|
||||
|
||||
我们经常会通过点击页面元素进入下一个网页,并立刻获取新页面的元素。但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。使用此方法,会阻塞程序,等待页面开始加载后再继续,从而避免上述问题。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `timeout`:超时时间
|
||||
|
||||
**返回:** 等待结束时是否进入加载状态
|
||||
|
||||
```python
|
||||
ele.click() # 点击某个元素
|
||||
page.wait_loading() # 等待页面进入加载状态
|
||||
# 执行在新页面的操作
|
||||
```
|
||||
|
||||
# ✔️切换页面模式
|
||||
|
||||
## 📍 `change_mode()`
|
||||
|
||||
此方法是`WebPage`用于切换模式的方法。
|
||||
|
||||
切换后默认在目标模式重新跳转到原模式所在 url。
|
||||
|
||||
参数:
|
||||
|
||||
- `mode`:目标模式字符串,`'s'`或`'d'`,默认转换到另一种
|
||||
- `go`:转换后是否跳转到原模式所在 url
|
||||
- `copy_cookies`:是否复制cookies到目标模式
|
||||
|
||||
返回:`None`
|
||||
|
||||
以下例子演示用浏览器登录 gitee 网站,再切换到 s 模式。可见 s 模式依然处于登录状态。
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
# 创建页面对象,默认 d 模式
|
||||
page = WebPage()
|
||||
# 访问个人中心页面(未登录,重定向到登录页面)
|
||||
page.get('https://gitee.com/profile')
|
||||
|
||||
# 打印当前模式和登录前的 title
|
||||
print('当前模式:', page.mode)
|
||||
print('登录前title:', page.title, '\n')
|
||||
|
||||
# 使用 d 模式输入账号密码登录
|
||||
page.ele('#user_login').input('your_user_name')
|
||||
page.ele('#user_password').input('your_password\n')
|
||||
page.wait_loading()
|
||||
|
||||
# 切换到 session 模式
|
||||
page.change_mode()
|
||||
|
||||
# 打印当前模式和登录后的 title()
|
||||
print('当前模式:', page.mode)
|
||||
print('登录后title:', page.title)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
当前模式:d
|
||||
登录前title: 登录 - Gitee.com
|
||||
|
||||
当前模式:s
|
||||
登录后title: 个人资料 - 码云 Gitee.com
|
||||
```
|
||||
|
||||
# ✔️ 执行脚本或命令
|
||||
|
||||
## 📍 `run_js()`
|
||||
|
||||
此方法用于执行 js 脚本,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `script`:js 脚本文本
|
||||
- `as_expr`:是否作为表达式运行,为`True`时`args`参数无效
|
||||
- `*args`:传入的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`...
|
||||
|
||||
**返回:** 脚本执行结果
|
||||
|
||||
```python
|
||||
# 用传入参数的方式执行 js 脚本显示弹出框显示 Hello world!
|
||||
page.run_js('alert(arguments[0]+arguments[1]);', 'Hello', ' world!')
|
||||
```
|
||||
|
||||
## 📍 `run_async_script()`
|
||||
|
||||
此方法用于以异步方式执行 js 代码,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `script`:js 文本
|
||||
- `as_expr`:是否作为表达式运行,为`True`时`args`参数无效
|
||||
- `*args`:传入 js 的参数,按顺序在js文本中对应`argument[0]`、`argument[1]`...
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 `run_cdp()`
|
||||
|
||||
此方法用于执行 Chrome DevTools Protocol 语句,d 模式独有。cdp
|
||||
用法详见[Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `cmd`:协议项目
|
||||
|
||||
- `**cmd_args`:项目参数
|
||||
|
||||
**返回:** 该语句返回的值
|
||||
|
||||
```python
|
||||
# 停止页面加载
|
||||
page.run_cdp('Page.stopLoading')
|
||||
```
|
||||
|
||||
# ✔️ cookies 及缓存
|
||||
|
||||
## 📍 `set_cookies()`
|
||||
|
||||
此方法用于对浏览器或`Session`对象设置 cookies,两种模式都支持。
|
||||
可以接收`CookieJar`、`list`、`tuple`、`str`、`dict`格式的 cookies。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `cookies`:cookies 信息
|
||||
- `set_session`:是否设置到`Session`对象
|
||||
- `set_driver`:是否设置到浏览器
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
cookies = {'name': 'abc'}
|
||||
page.set_cookies(cookies, set_session=True, set_driver=True)
|
||||
```
|
||||
|
||||
## 📍 `cookies_to_session()`
|
||||
|
||||
此方法用于从浏览器复制 cookies 到`Session`对象。不会触发模式切换。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `copy_user_agent`:是否同时复制 user agent 信息
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.cookies_to_session()
|
||||
```
|
||||
|
||||
## 📍 `cookies_to_driver()`
|
||||
|
||||
此方法用于从`Session`对象复制 cookies 到浏览器。不会触发模式切换。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 `set_session_storage()`
|
||||
|
||||
此方法用于设置或删除某项 sessionStorage 信息,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `item`:要设置的项
|
||||
|
||||
- `value`:项的值,设置为`False`时,删除该项
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.set_session_storage(item='abc', value='123')
|
||||
```
|
||||
|
||||
## 📍 `set_local_storage()`
|
||||
|
||||
此方法用于设置或删除某项 localStorage 信息,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `item`:要设置的项
|
||||
|
||||
- `value`:项的值,设置为`False`时,删除该项
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 `clear_cache()`
|
||||
|
||||
此方法用于清除缓存,可选要清除的项,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `session_storage`:是否清除 sessionstorage
|
||||
|
||||
- `local_storage`:是否清除 localStorage
|
||||
|
||||
- `cache`:是否清除 cache
|
||||
|
||||
- `cookies`:是否清除 cookies
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.clear_cache(cookies=False) # 除了 cookies,其它都清除
|
||||
```
|
||||
|
||||
# ✔️ 各种设置
|
||||
|
||||
## 📍 `set_timeouts()`
|
||||
|
||||
此方法用于设置三种超时时间,单位为秒。可单独设置,为`None`表示不改变原来设置。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `implicit`:查找元素超时时间
|
||||
- `page_load`:页面加载超时时间
|
||||
- `lscript`:脚本运行超时时间
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.set_timeouts(implicit=10, page_load=30)
|
||||
```
|
||||
|
||||
## 📍 `set_page_load_strategy`
|
||||
|
||||
此属性用于设置页面加载策略,d 模式独有。
|
||||
|
||||
页面加载策略有三种:
|
||||
|
||||
- `normal`:等待页面完全加载完成,为默认状态
|
||||
|
||||
- `eager`:等待文档加载完成就结束,不等待资源加载
|
||||
|
||||
- `none`:页面连接完成就结束
|
||||
|
||||
```python
|
||||
page.set_page_load_strategy.eager()
|
||||
```
|
||||
|
||||
## 📍 `set_ua_to_tab()`
|
||||
|
||||
此方法用于为浏览器当前标签页设置 user agent,只在当前 tab 有效,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `ua`:user agent 字符串
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 `set_headers()`
|
||||
|
||||
此方法用于设置headers参数,两种模式都支持。s 模式下,新 headers 值会逐项覆盖原来的,不会删除原来未被设置的值。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `headers`:`dict`形式的 headers
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
h = {'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'}
|
||||
page.set_headers(headers=h)
|
||||
```
|
||||
|
||||
# ✔️ 窗口管理
|
||||
|
||||
## 📍 调整大小和位置
|
||||
|
||||
`set_window`属性返回一个`WindowSetter`对象,用于执行改变窗口的各种方法,d 模式独有。
|
||||
|
||||
| 方法 | 参数 | 说明 |
|
||||
| --------------------- | ---- | ---- |
|
||||
| `maximized()` | 无 | 最大化 |
|
||||
| `minimized()` | 无 | 最小化 |
|
||||
| `fullscreen()` | 无 | 全屏 |
|
||||
| `normal()` | 无 | 常规 |
|
||||
| `size(width, height)` | 宽,高 | 设置大小 |
|
||||
| `location(x, y)` | 屏幕坐标 | 设置位置 |
|
||||
|
||||
```python
|
||||
# 窗口最大化
|
||||
page.set_window.maximized()
|
||||
|
||||
# 窗口全屏,即 F11
|
||||
page.set_window.fullscreen()
|
||||
|
||||
# 恢复普通窗口
|
||||
page.set_window.normal()
|
||||
|
||||
# 设置窗口大小
|
||||
page.set_window.size(500, 500)
|
||||
|
||||
# 设置窗口位置
|
||||
page.set_window.location(200, 200)
|
||||
```
|
||||
|
||||
## 📍 隐藏和显示窗口
|
||||
|
||||
`hide_browser()`和`show_browser()`方法用于随时隐藏和显示浏览器窗口,d 模式独有。
|
||||
|
||||
与 headless 模式不一样,这两个方法是直接隐藏和显示浏览器进程。在任务栏上也会消失。
|
||||
|
||||
只支持 Windows 系统,并且必须已安装 pypiwin32 库才可使用。
|
||||
|
||||
`hide_browser()`
|
||||
|
||||
**参数:** 无
|
||||
|
||||
返回:`None`
|
||||
|
||||
`show_browser()`
|
||||
|
||||
**参数:** 无
|
||||
|
||||
返回:`None`
|
||||
|
||||
```python
|
||||
page.hide_browser()
|
||||
```
|
||||
|
||||
**注意:**
|
||||
|
||||
- 浏览器隐藏后并没有关闭,下次运行程序还会接管已隐藏的浏览器
|
||||
|
||||
- 浏览器隐藏后,如果有新建标签页,会自行显示出来
|
||||
|
||||
# ✔️ 滚动页面
|
||||
|
||||
## 📍 `scroll`
|
||||
|
||||
此属性用于以某种方式滚动页面,d 模式独有。
|
||||
调用此属性返回一个`Scroll`对象,调用该对象方法实现各种方式的滚动。
|
||||
|
||||
| 方法 | 参数说明 | 功能 |
|
||||
| ------------------- | ------ | ---------------- |
|
||||
| `to_top()` | 无 | 滚动到顶端,水平位置不变 |
|
||||
| `to_bottom()` | 无 | 滚动到底端,水平位置不变 |
|
||||
| `to_half()` | 无 | 滚动到垂直中间位置,水平位置不变 |
|
||||
| `to_rightmost()` | 无 | 滚动到最右边,垂直位置不变 |
|
||||
| `to_leftmost()` | 无 | 滚动到最左边,垂直位置不变 |
|
||||
| `to_location(x, y)` | 滚动条坐标值 | 滚动到指定位置 |
|
||||
| `up(pixel)` | 滚动的像素 | 向上滚动若干像素,水平位置不变 |
|
||||
| `down(pixel)` | 滚动的像素 | 向下滚动若干像素,水平位置不变 |
|
||||
| `right(pixel)` | 滚动的像素 | 向左滚动若干像素,垂直位置不变 |
|
||||
| `left(pixel)` | 滚动的像素 | 向右滚动若干像素,垂直位置不变 |
|
||||
|
||||
```python
|
||||
# 页面滚动到底部
|
||||
page.scroll.to_bottom()
|
||||
|
||||
# 页面滚动到最右边
|
||||
page.scroll.to_rightmost()
|
||||
|
||||
# 页面向下滚动 200 像素
|
||||
page.scroll.down(200)
|
||||
|
||||
# 滚动到指定位置
|
||||
page.scroll.to_location(100, 300)
|
||||
```
|
||||
|
||||
## 📍 `scroll_to_see()`
|
||||
|
||||
此方法用于滚动页面直到元素可见,d 模式独有。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `loc_or_ele`:元素的定位信息,可以是元素、定位符
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
# 滚动到某个已获取到的元素
|
||||
ele = page.ele('tag:div')
|
||||
page.scroll_to_see(ele)
|
||||
|
||||
# 滚动到按定位符查找到的元素
|
||||
page.scroll_to_see('tag:div')
|
||||
```
|
||||
|
||||
# ✔️ 处理弹出消息
|
||||
|
||||
## 📍 `handle_alert()`
|
||||
|
||||
此方法 用于处理提示框,d 模式独有。
|
||||
它能够设置等待时间,等待提示框出现才进行处理,若超时没等到提示框,返回`None`。
|
||||
它可只获取提示框文本而不处理提示框。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `accept`:`True`表示确认,`False`表示取消,其它值不会按按钮但依然返回文本值
|
||||
- `send`:处理 prompt 提示框时可输入文本
|
||||
- `timeout`:等待提示框出现的超时时间
|
||||
|
||||
**返回:** 提示框内容文本,未等到提示框则返回`None`
|
||||
|
||||
```python
|
||||
# 确认提示框并获取提示框文本
|
||||
txt = page.handle_alert()
|
||||
|
||||
# 点击取消
|
||||
page.handle_alert(accept=False)
|
||||
|
||||
# 给 prompt 提示框输入文本并点击确定
|
||||
paeg.handle_alert(accept=True, send='some text')
|
||||
|
||||
# 不处理提示框,只获取提示框文本
|
||||
txt = page.handle_alert(accept=None)
|
||||
```
|
||||
|
||||
# ✔️ 关闭
|
||||
|
||||
## 📍 `close_driver()`
|
||||
|
||||
此方法用于关闭`WebPage`控制的浏览器,并切换到 s 模式。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.close_driver()
|
||||
```
|
||||
|
||||
## 📍 `close_session()`
|
||||
|
||||
此方法用于关闭`WebPage`控制的`Session`对象,并切换到 d 模式。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:`**None`
|
||||
|
||||
```python
|
||||
page.close_session()
|
||||
```
|
||||
|
||||
## 📍`quit()`
|
||||
|
||||
此方法用于退出浏览器并且关闭 Session 对象。彻底关闭`WebPage`对象。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:`**None`
|
||||
|
||||
```python
|
||||
page.quit()
|
||||
```
|
@ -1,242 +0,0 @@
|
||||
本节介绍对浏览器标签页的管理及使用技巧。
|
||||
|
||||
与 selenium 不同,`WebPage`能够用多个标签页对象同时操作多个标签页,而无须切入切出,并且,标签页无须在激活状态也可以控制。因此能够实现一些非常灵活的使用方式。
|
||||
|
||||
比如多线程分别独立控制标签页,或一个总标签页,控制多个从标签页,或者配合插件实现浏览器随时更换代理等。
|
||||
|
||||
`WebPage`或`ChromiumPage`对象为浏览器标签页总管,可以控制标签页的增删。`ChromiumTab`对象为独立的标签页对象,可控制每个标签页内的操作。
|
||||
|
||||
# ✔️ 标签页总览
|
||||
|
||||
## 📍 `tabs_count`
|
||||
|
||||
此属性返回标签页数量。
|
||||
|
||||
```python
|
||||
print(page.tabs_count)
|
||||
# 输出:2
|
||||
```
|
||||
|
||||
## 📍 `tabs`
|
||||
|
||||
此属性以`list`方式返回所有标签页 id。
|
||||
|
||||
```python
|
||||
print(page.tabs)
|
||||
# 输出:['0B300BEA6F1F1F4D5DE406872B79B1AD', 'B838E91F38121B32940B47E8AC59D015']
|
||||
```
|
||||
|
||||
# ✔️ 新建标签页
|
||||
|
||||
## 📍 `new_tab()`
|
||||
|
||||
该方法用于新建一个标签页,该标签页在最后面。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `url`:新标签页跳转到的网址,不传入则新建空标签页
|
||||
|
||||
- `switch_to`:新建标签页后是否把焦点移过去,默认为跳转
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
page.new_tab(url='https://www.baidu.com')
|
||||
```
|
||||
|
||||
# ✔️ 关闭标签页
|
||||
|
||||
## 📍 `close_tabs()`
|
||||
|
||||
此方法用于关闭指定的标签页,可关闭多个。默认关闭当前的。
|
||||
|
||||
如果被关闭的标签页包含当前页,会跳转到剩下的第一个页面,但未必是视觉上第一个。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_ids`:要关闭的标签页 id,可传入 id 组成的列表或元组,为`None`时关闭当前页
|
||||
- `others`:是否关闭指定标签页之外的
|
||||
|
||||
返回:`None`
|
||||
|
||||
```python
|
||||
# 关闭当前标签页
|
||||
page.close_tabs()
|
||||
|
||||
# 关闭第1、3个标签页
|
||||
tabs = page.tabs
|
||||
page.close_tabs(tab_ids=(tabs[0], tabs[2]))
|
||||
```
|
||||
|
||||
## 📍 `close_other_tabs()`
|
||||
|
||||
此方法用于关闭传入的标签页以外标签页,默认保留当前页。可传入多个。
|
||||
|
||||
如果被关闭的标签页包含当前页,会跳转到剩下的第一个页面,但未必是视觉上第一个。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_ids`:要保留的标签页 id,可传入 id 组成的列表或元组,为`None`时保存当前页
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
# 关闭除当前标签页外的所有标签页
|
||||
page.close_other_tabs()
|
||||
|
||||
# 关闭除第一个以外的标签页
|
||||
page.close_other_tabs(page.tab[0])
|
||||
|
||||
# 关闭除 id 为 aaaaa 和 bbbbb 以外的标签页
|
||||
reserve_list = ('aaaaa', 'bbbbb')
|
||||
page.close_other_tabs(reserve_list)
|
||||
```
|
||||
|
||||
# ✔️ 切换标签页
|
||||
|
||||
## 📍 `main_tab`
|
||||
|
||||
日常使用时,经常会用一个标签页作为主标签页,产生众多临时标签页去进行操作。因此我们可以为每个`WebPage`或`ChromiumPage`对象设置一个标签页为主标签页,方便随时切换。
|
||||
|
||||
默认接管浏览器时活动标签页则为主标签页。
|
||||
|
||||
```python
|
||||
print(page.main_tab)
|
||||
# 输出:'0B300BEA6F1F1F4D5DE406872B79B1AD'
|
||||
```
|
||||
|
||||
## 📍 `set_main_tab()`
|
||||
|
||||
此方法用于设置某个标签页为主标签页。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_id`:要设置的标签页 id,不传入则设置当前标签页为主
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
# 指定一个标签页为主标签页
|
||||
page.set_main_tab(tab_id='0B300BEA6F1F1F4D5DE406872B79B1AD')
|
||||
|
||||
# 设置当前控制的标签页为主标签页
|
||||
```
|
||||
|
||||
## 📍`to_main_tab()`
|
||||
|
||||
此方法用于把焦点定位到主标签页,使当前对象控制目标改为主标签页。
|
||||
|
||||
```python
|
||||
page.to_main_tab()
|
||||
```
|
||||
|
||||
## 📍 `to_tab()`
|
||||
|
||||
此方法把焦点定位到某个标签页,使当前对象控制目标改为该标签页。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_id`:标签页 id,默认切换到主标签页
|
||||
- `activate`:切换后是否变为活动状态
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
```python
|
||||
# 跳转到主标签页
|
||||
page.to_tab()
|
||||
|
||||
# 跳转到第一个标签页
|
||||
page.to_tab(page.tabs[0])
|
||||
|
||||
# 跳转到 id 为该字符串的标签页
|
||||
page.to_tab('0B300BEA6F1F1F4D5DE406872B79B1AD')
|
||||
```
|
||||
|
||||
## 📍 `to_front()`
|
||||
|
||||
此方法用于激活当前标签页使其处于最前面。标签页无须在活动状态程序也能操控。
|
||||
|
||||
**参数:** 无
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
# ✔️ 多标签页协同
|
||||
|
||||
## 📍 获取标签页对象
|
||||
|
||||
可以用`WebPage`或`ChromiumPage`的`get_tab()`方法获取标签页对象,然后可以使用这个对象对标签页进行操作。
|
||||
|
||||
`get_tab()`
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_id`:要获取的标签页 id,为`None`时获取当前标签页
|
||||
|
||||
**返回:**`ChromiumTab`对象
|
||||
|
||||
```python
|
||||
tab = page.get_tab() # 获取当前标签页对象
|
||||
```
|
||||
|
||||
## 📍 使用标签页对象
|
||||
|
||||
每个`ChromiumTab`对象控制一个浏览器标签页,方法和直接使用`ChromiumPage`一致,只比`ChromiumPage`少了控制标签页功能。
|
||||
|
||||
```python
|
||||
tab.get('https://www.baidu.com') # 使用标签页对象
|
||||
```
|
||||
|
||||
## 📍 同时控制多标签页示例
|
||||
|
||||
下面的例子演示多个线程控制多个标签页进行内容采集。
|
||||
|
||||
```python
|
||||
from threading import Thread
|
||||
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
|
||||
def 采集(tab):
|
||||
# 采集 4 页
|
||||
for _ in range(4):
|
||||
# 获取某页所有库名称并打印
|
||||
for i in tab.eles('.title project-namespace-path'):
|
||||
print(i.text)
|
||||
|
||||
# 点击翻页
|
||||
tab('@rel=next').click()
|
||||
# 等待页面进入加载
|
||||
tab.wait_loading()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 新建页面对象
|
||||
page = ChromiumPage()
|
||||
# 第一个标签页访问网址
|
||||
page.get('https://gitee.com/explore/ai')
|
||||
# 获取第一个标签页对象
|
||||
tab1 = page.get_tab()
|
||||
# 新建一个标签页并访问另一个网址
|
||||
page.new_tab('https://gitee.com/explore/machine-learning')
|
||||
# 获取第二个标签页对象
|
||||
tab2 = page.get_tab()
|
||||
|
||||
# 多线程同时处理多个页面
|
||||
Thread(target=采集, args=(tab1,)).start()
|
||||
Thread(target=采集, args=(tab2,)).start()
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```console
|
||||
MindSpore/mindspore
|
||||
PaddlePaddle/Paddle
|
||||
MindSpore/docs
|
||||
scruel/Notes-ML-AndrewNg
|
||||
MindSpore/graphengine
|
||||
inspur-inna/inna1.0
|
||||
MindSpore/course
|
||||
MindSpore/community
|
||||
|
||||
后面省略。。。
|
||||
```
|
143
docs/_sidebar.md
143
docs/_sidebar.md
@ -1,77 +1,90 @@
|
||||
* [📣 1 概述](README.md)
|
||||
|
||||
* [☀️ 2 特性和亮点](#)
|
||||
|
||||
* [💖 2.1 贴心设计](特性和亮点\贴心设计.md)
|
||||
* [🌟 2.2 特性演示](#)
|
||||
* [⭐ 与 requests 对比](特性和亮点\特性演示\与requests代码对比.md)
|
||||
* [⭐ 与 selenium 对比](特性和亮点\特性演示\与selenium代码对比.md)
|
||||
* [⭐ 模式切换](特性和亮点\特性演示\模式切换.md)
|
||||
* [⭐ 获取并打印元素属性](特性和亮点\特性演示\获取并打印元素属性.md)
|
||||
* [⭐ 下载文件](特性和亮点\特性演示\下载文件.md)
|
||||
|
||||
* [💖 2.1 贴心设计](2_features\1_intimate_design.md)
|
||||
* [🌟 2.2 特性演示](#)
|
||||
* [⭐ 与 requests 对比](2_features\2_features_demos\1_compare_with_requests.md)
|
||||
* [⭐ 与 selenium 对比](2_features\2_features_demos\2_compare_with_selenium.md)
|
||||
* [⭐ 模式切换](2_features\2_features_demos\3_switch_mode.md)
|
||||
* [⭐ 获取元素属性](2_features\2_features_demos\4_get_element_attributes.md)
|
||||
* [⭐ 下载文件](2_features\2_features_demos\5_download_file.md)
|
||||
|
||||
* [🧭 3 入门指南](#)
|
||||
|
||||
* [🌏 3.1 安装和导入](入门指南\安装和导入.md)
|
||||
* [🌏 3.2 准备工作](入门指南\准备工作.md)
|
||||
* [🌏 3.3 上手示例](#)
|
||||
* [🌐 控制浏览器](入门指南\上手示例\控制浏览器.md)
|
||||
* [🌐 收发数据包](入门指南\上手示例\收发数据包.md)
|
||||
* [🌐 模式切换](入门指南\上手示例\模式切换.md)
|
||||
* [🌏 3.4 基本概念](入门指南\基本概念.md)
|
||||
|
||||
* [🛠 4 使用方法](#)
|
||||
|
||||
* [🔨 4.1 创建页面对象](WebPage使用方法\3.1创建页面对象.md)
|
||||
* [🔨 4.2 访问网页](WebPage使用方法\3.2访问网页.md)
|
||||
* [🔨 4.3 查找元素](WebPage使用方法\3.3查找元素.md)
|
||||
* [🔨 4.4 获取元素信息](WebPage使用方法\3.4获取元素信息.md)
|
||||
* [🔨 4.5 元素操作](WebPage使用方法\3.5元素操作.md)
|
||||
* [🔨 4.6 获取网页信息](WebPage使用方法\3.6获取网页信息.md)
|
||||
* [🔨 4.7 页面操作](WebPage使用方法\3.7页面操作.md)
|
||||
* [🔨 4.8 标签页操作](WebPage使用方法\3.8标签页操作.md)
|
||||
* [🔨 4.9 iframe操作](WebPage使用方法\3.9iframe操作.md)
|
||||
* [🔨 4.10 动作链](WebPage使用方法\3.10动作链.md)
|
||||
* [🔨 4.11 下载文件](WebPage使用方法\下载文件.md)
|
||||
* [🌏 3.1 安装和导入](3_get_start\1_installation_and_import.md)
|
||||
* [🌏 3.2 准备工作](3_get_start\2_before_start.md)
|
||||
* [🌏 3.3 上手示例](#)
|
||||
* [🗺️ 操控浏览器](3_get_start\3_examples\1_control_browser.md)
|
||||
* [🗺️ 收发数据包](3_get_start\3_examples\2_data_packets.md)
|
||||
* [🗺️ 模式切换](3_get_start\3_examples\3_switch_mode.md)
|
||||
* [🌏 3.4 基本概念](3_get_start\4_basic_concept.md)
|
||||
|
||||
* [📝 5 启动配置](#)
|
||||
|
||||
* [🗒️ 5.1 概述](启动配置\概述.md)
|
||||
* [🗒️ 5.2 浏览器启动配置](启动配置\浏览器启动配置.md)
|
||||
* [🗒️ 5.3 Session 启动配置](启动配置\Session启动配置.md)
|
||||
* [🗒️ 5.4 使用配置文件](启动配置\使用配置文件.md)
|
||||
* [🗒️ 5.5 easy_set 方法](启动配置\easy_set方法.md)
|
||||
* [📫 4 SessionPage](#)
|
||||
|
||||
* [🧰 6 进阶使用](#)
|
||||
|
||||
* [⚙️ 6.1 打包程序](进阶使用\打包程序.md)
|
||||
* [⚙️ 6.2 监听浏览器网络](进阶使用\监听浏览器网络.md)
|
||||
* [⚙️ 6.3 下载文件](进阶使用\下载文件.md)
|
||||
* [✉️ 4.0 概述](4_SessionPge\0_introduction.md)
|
||||
* [✉️ 4.1 创建页面对象](4_SessionPge\1_create_page_object.md)
|
||||
* [✉️ 4.2 访问网页](4_SessionPge\2_visit_web_page.md)
|
||||
* [✉️ 4.3 获取网页信息](4_SessionPge\3_get_page_info.md)
|
||||
* [✉️ 4.4 查找元素](4_SessionPge\4_find_elements.md)
|
||||
* [✉️ 4.5 获取元素信息](4_SessionPge\5_get_element_info.md)
|
||||
* [✉️ 4.6 启动配置](4_SessionPge\6_session_options.md)
|
||||
|
||||
* [🛠 7 旧版使用方法](#)
|
||||
|
||||
* [🔨 7.0 简介](MixPage使用方法\简介.md)
|
||||
* [🔨 7.1 创建页面对象](MixPage使用方法\创建页面对象.md)
|
||||
* [🔨 7.2 访问网页](MixPage使用方法\访问网页.md)
|
||||
* [🔨 7.3 查找页面元素](MixPage使用方法\查找页面元素.md)
|
||||
* [🔨 7.4 获取元素信息](MixPage使用方法\获取元素信息.md)
|
||||
* [🔨 7.5 元素操作](MixPage使用方法\元素操作.md)
|
||||
* [🔨 7.6 获取网页信息](MixPage使用方法\获取网页信息.md)
|
||||
* [🔨 7.7 页面操作](MixPage使用方法\页面操作.md)
|
||||
* [🔨 7.8 cookies 的使用](MixPage使用方法\cookies的使用.md)
|
||||
* [🔨 7.9 Drission 对象](MixPage使用方法\Drission对象.md)
|
||||
* [🔨 7.10 对接 selenium 及 requests 代码](MixPage使用方法\对接selenium及requests代码.md)
|
||||
* [🔨 7.11 使用其它系统或浏览器](MixPage使用方法\使用其它系统或浏览器.md)
|
||||
* [🔨 7.12 DriverPage 和 SessionPage](MixPage使用方法\DriverPage和SessionPage.md)
|
||||
* [🚀 5 ChromiumPage](#)
|
||||
|
||||
* [⚡️ 8 示例和技巧](#)
|
||||
|
||||
* [🌠 自动登录码云](示例和技巧\自动登录码云.md)
|
||||
* [🌠 采集猫眼电影TOP100榜](示例和技巧\采集猫眼电影TOP100榜.md)
|
||||
* [🌠 下载星巴克产品图片](示例和技巧\下载星巴克产品图片.md)
|
||||
* [🌠 下载豆瓣图书封面图片](示例和技巧\下载豆瓣图书封面图片.md)
|
||||
* [🌠 多线程操作多标签页](示例和技巧\多线程操作多标签页.md)
|
||||
* [🛰️ 5.0 概述](5_ChromiumPage\0_introduction.md)
|
||||
* [🛰️ 5.1 创建页面对象](5_ChromiumPage\1_create_page_object.md)
|
||||
* [🛰️ 5.2 访问网页](5_ChromiumPage\2_visit_web_page.md)
|
||||
* [🛰️ 5.3 获取网页信息](5_ChromiumPage\3_get_page_info.md)
|
||||
* [🛰️ 5.4 页面交互](5_ChromiumPage\4_page_operation.md)
|
||||
* [🛰️ 5.5 查找元素](5_ChromiumPage\5_find_elements.md)
|
||||
* [🛰️ 5.6 获取元素信息](5_ChromiumPage\6_get_element_info.md)
|
||||
* [🛰️ 5.7 元素交互](5_ChromiumPage\7_element_operation.md)
|
||||
* [🛰️ 5.8 标签页操作](5_ChromiumPage\8_tab_operation.md)
|
||||
* [🛰️ 5.9 iframe 操作](5_ChromiumPage\9_frame_operation.md)
|
||||
* [🛰️ 5.10 动作链](5_ChromiumPage\10_action_chains.md)
|
||||
* [🛰️ 5.11 浏览器启动配置](5_ChromiumPage\11_browser_options.md)
|
||||
|
||||
* [🔖 9 版本历史](版本历史.md)
|
||||
* [🌌 6 WebPage](#)
|
||||
|
||||
* [💐 鸣谢](鸣谢.md)
|
||||
* [🪐 6.0 概述](6_WebPage\0_introduction.md)
|
||||
* [🪐 6.1 创建页面对象](6_WebPage\1_create_page_object.md)
|
||||
* [🪐 6.2 模式切换](6_WebPage\2_mode_switch.md)
|
||||
* [🪐 6.3 独有的功能](6_WebPage\3_webpage_function.md)
|
||||
|
||||
* [🧰 7 进阶使用](#)
|
||||
|
||||
* [⚙️ 7.1 配置文件的使用](7_advance\1_ini_file.md)
|
||||
* [⚙️ 7.2 easy_set 方法](7_advance\2_easy_set.md)
|
||||
* [⚙️ 7.3 下载文件](7_advance\3_download.md)
|
||||
* [⚙️ 7.4 加速浏览器数据采集](7_advance\4_accelerate_collecting.md)
|
||||
* [⚙️ 7.5 打包程序](7_advance\5_packaging.md)
|
||||
* [⚙️ 7.6 监听浏览器网络](7_advance\6_monitor_network.md)
|
||||
|
||||
* [🛠 8 旧版使用方法](#)
|
||||
|
||||
* [🔨 8.0 概述](8_MixPage\0_introduction.md)
|
||||
* [🔨 8.1 创建页面对象](8_MixPage\1_create_page_object.md)
|
||||
* [🔨 8.2 访问网页](8_MixPage\2_visit_web_page.md)
|
||||
* [🔨 8.3 查找页面元素](8_MixPage\3_find_page_element.md)
|
||||
* [🔨 8.4 获取元素信息](8_MixPage\4_get_element_info.md)
|
||||
* [🔨 8.5 元素操作](8_MixPage\5_element_operation.md)
|
||||
* [🔨 8.6 获取网页信息](8_MixPage\6_get_page_info.md)
|
||||
* [🔨 8.7 页面操作](8_MixPage\7_page_operation.md)
|
||||
* [🔨 8.8 cookies 的使用](8_MixPage\8_cookies.md)
|
||||
* [🔨 8.9 Drission 对象](8_MixPage\9_Drission.md)
|
||||
* [🔨 8.10 对接 selenium 及 requests 代码](8_MixPage\10_work_with_selenium_and_requests.md)
|
||||
* [🔨 8.11 使用其它系统或浏览器](8_MixPage\11_use_other_browser.md)
|
||||
* [🔨 8.12 DriverPage 和 SessionPage](8_MixPage\12_DriverPage_and_SessionPage.md)
|
||||
|
||||
* [⚡️ 9 示例和技巧](#)
|
||||
|
||||
* [🌠 自动登录码云](9_demos\login_gitee.md)
|
||||
* [🌠 采集猫眼电影 TOP100 榜](9_demos\maoyan_TOP100.md)
|
||||
* [🌠 下载星巴克产品图片](9_demos\starbucks_pics.md)
|
||||
* [🌠 下载豆瓣图书封面图片](9_demos\douban_book_pics.md)
|
||||
* [🌠 多线程操作多标签页](9_demos\multithreading_with_tabs.md)
|
||||
|
||||
* [🔖 10 版本历史](10_history.md)
|
||||
|
||||
* [💐 鸣谢](thx.md)
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +0,0 @@
|
||||
浏览器和连接的配置很复杂,若都写在代码中,会让代码看上去很臃肿。
|
||||
因此,本库提供了一些方法简化其使用。
|
||||
|
||||
- 使用 ini 文件记录常用配置,使配置便于复用,无须在代码中编写繁琐的配置。
|
||||
- 使用`ChromiumOptions`对象管理浏览器配置。
|
||||
- 使用`SessionOptions`对象管理`Session`对象配置。
|
||||
- 提供 easy_set 方法,专门用于对 ini 文件中常用配置进行管理,简化配置操作。
|
Loading…
x
Reference in New Issue
Block a user