461 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

只有 d 模式下才能对元素进行操作,本节介绍普通元素`ChromiumElement`内置方法。
iframe 元素`ChromiumFrame`使用方法后面章节单独介绍。
# ✔️ 点击元素
## 📍 `click()`
此方法用于点击元素。可选择模拟点击或 js 点击。
还可以在点击被遮挡时执行重试。`retry`参数为`True``by_js`参数为`None`时,会先用模拟方式点击,若遇到其它元素遮挡,会重试点击直到超时。若都失败,自动改用 js 方式进行点击。
`by_js`参数为`True`时,只会通过 js 点击一次,不会重试。
此设计除了可保证点击成功,还可以用于检测页面上的遮罩层是否消失。遮罩层经常出现在 js 方式翻页的时候,它的覆盖会阻碍模拟点击,所以可以通过对其下面的元素不断重试点击,来判断遮罩层是否存在。当然,这个方法是否可行要看具体网页设计。
而如果直接使用 js 进行点击,则可无视任何遮挡,只要元素在 DOM 内,就能点击得到,这样可以根据须要灵活地对元素进行操作。
通常,点击链接后立刻获取新页面的元素,程序可自动等待元素加载,但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。可以把`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.click()
# 用 js 方式点击 ele 元素
ele.click(by_js=True)
# 假设遮罩层出现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`:相对元素左上角坐标的 x 轴偏移量
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
- `button`:点击哪个键,传入`'left'``'right'``'middle'`
**返回:**`None`
```python
# 点击元素右上方 50*50 的位置
ele.click_at(50, -50)
# 点击元素上中部x 相对左上角向右偏移50y 保持在元素中点
ele.click_at(offset_x=50)
# 和 click() 相似,但没有重试功能
ele.click_at()
```
## 📍 `r_click()`
此方法实现右键单击元素。
**参数:**
**返回:**`None`
```python
ele.r_click()
```
## 📍 `r_click_at()`
此方法用于带偏移量右键点击元素,用法和`click_at()`相似。
**参数:**
- `offset_x`:相对元素左上角坐标的 x 轴偏移量
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
**返回:**`None`
```python
# 点击距离元素左上角 50*50 的位置(位于元素内部)
ele.r_click_at(50, 50)
```
## 📍 `m_click()`
此方法实现中键单击元素。
**参数:**
**返回:**`None`
```python
ele.m_click()
```
# ✔️ 输入内容
## 📍 `clear()`
此方法用于清空元素文本,可选择模拟按键或 js 方式。
模拟按键方式会自动输入`ctrl-a-del`组合键来清除文本框js 方式则直接把元素`value`属性设置为`''`
**参数:**
- `by_js`:是否用 js 方式清空
**返回:**`None`
```python
ele.clear()
```
## 📍 `input()`
此方法用于向元素输入文本或组合键,也可用于输入文件路径到`input`元素。可选择输入前是否清空元素。
组合键以`tuple`方式传入。
多行上传控件,多个路径以`list``tuple`或以`\n`分隔的字符串传入。
?> **Tips:** <br>- 有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上`'\n'`<br>- 会自动把非`str`数据转换为`str`
**参数:**
- `vals`:文本值或按键组合,
- `clear`:输入前是否清空文本框
**返回:**`None`
```python
# 输入文本
ele.input('Hello world!')
# 输入文本并回车
ele.input('Hello world!\n')
```
## 📍 输入组合键
使用组合键或要传入特殊按键前,先要导入按键类`Keys`
```python
from DrissionPage.keys import Keys
```
然后将组合键放在一个`tuple`中传入`input()`即可。
```python
from DrissionPage.keys import Keys
ele.input((Keys.CTRL, 'a', Keys.DEL)) # ctrl+a+del
```
## 📍 上传文件
上传文件是用`input()``type`属性为`'file'``<input>`元素进行输入,把文件路径输入到元素即可,用法与输入文本一致。
稍有不同的是,无论`clear`参数是什么,都会清空原控件内容。
多文件上传控件,多个路径以`list``tuple`或以`\n`分隔的字符串传入。
```python
# 传入一个路径
ele.input('D:\\test1.txt')
# 传入多个路径,方式 1
paths = 'D:\\test1.txt\nD:\\test2.txt'
ele.input(paths)
# 传入多个路径,方式 2
paths = ['D:\\test1.txt', 'D:\\test2.txt']
ele.input(paths)
```
# ✔️ 拖拽和悬停
?> 除了以下方法,本库还提供更灵活的动作链`ActionChains`功能,详见后面章节。
## 📍 `drag()`
此方法用于拖拽元素到相对于当前的一个新位置,可以设置速度,可以选择是否随机抖动。
**参数:**
- `offset_x`x 变化值
- `offset_y`y 变化值
- `speed`:拖动的速度,传入 0 即瞬间到达
- `shake`:是否随机抖动
**返回:**`None`
```python
# 拖动当前元素到距离 50*50 的位置,速度为 100不随机抖动
ele.drag(50, 50, 100, False)
```
## 📍 `drag_to()`
此方法用于拖拽元素到另一个元素上或一个坐标上。
**参数:**
- `ele_or_loc` 另一个元素对象或坐标元组
- `speed` 拖动的速度,传入 0 即瞬间到达
- `shake` 是否随机抖动
**返回:**`None`
```python
# 把 ele1 拖拽到 ele2 上
ele1 = page.ele('#div1')
ele2 = page.ele('#div2')
ele1.drag_to(ele2)
# 把 ele1 拖拽到网页 50, 50 的位置
ele1.drag_to((50, 50))
```
## 📍 `hover()`
此方法用于模拟鼠标悬停在元素上,可接受偏移量,偏移量相对于元素左上角坐标。不传入`offset_x``offset_y`值时悬停在元素中点。
**参数:**
- `offset_x`:相对元素左上角坐标的 x 轴偏移量
- `offset_y`:相对元素左上角坐标的 y 轴偏移量
**返回:**`None`
```python
# 悬停在元素右上方 50*50 的位置
ele.hover(50, -50)
# 悬停在元素上中部x 相对左上角向右偏移50y 保持在元素中点
ele.hover(offset_x=50)
# 悬停在元素中点
ele.hover()
```
# ✔️ 修改元素
## 📍 `set_innerHTML()`
此方法用于设置元素的 innerHTML内容。
**参数:**
- `html`html文本
**返回:**`None`
## 📍 `set_prop()`
此方法用于设置元素`property`属性。
**参数:**
- `prop` 属性名
- `value` 属性值
**返回:**`None`
```python
ele.set_prop('value', 'Hello world!')
```
## 📍 `set_attr()`
此方法用于设置元素`attribute`属性。
**参数:**
- `attr`:属性名
- `value`:属性值
**返回:**`None`
```python
ele.set_attr('href', 'http://www.gitee.com')
```
## 📍 `remove_attr()`
此方法用于删除元素`attribute`属性。
**参数:**
- `attr`:属性名
**返回:**`None`
```python
ele.remove_attr('href')
```
# ✔️ 执行 js 脚本
## 📍 `run_js()`
此方法用于对元素执行 js 代码,代码中用`this`表示元素自己。
**参数:**
- `script`js 脚本文本
- `as_expr`:是否作为表达式运行,为`True``args`参数无效
- `*args`:传入 js 的参数按顺序在js文本中对应`argument[0]``argument[1]`...
**返回:** js 执行的结果
!>**注意:**<br>要获取 js 结果记得写上`return`
```python
# 用执行 js 的方式点击元素
ele.run_js('this.click();')
# 用 js 获取元素高度
height = ele.run_js('return this.offsetHeight;')
```
## 📍 `run_async_script()`
此方法用于以异步方式执行 js 代码,代码中用`this`表示元素自己。
**返回:**`None`
# ✔️ 元素滚动
## 📍 `scroll`
此属性用于以某种方式滚动元素中的滚动条。
调用此属性返回一个`ChromiumScroll`对象,调用该对象的方法实现各种方式的滚动。
| 方法 | 参数说明 | 功能 |
|:-------------------:|:------:|:----------------:|
| `to_top()` | 无 | 滚动到顶端,水平位置不变 |
| `to_bottom()` | 无 | 滚动到底端,水平位置不变 |
| `to_half()` | 无 | 滚动到垂直中间位置,水平位置不变 |
| `to_rightmost()` | 无 | 滚动到最右边,垂直位置不变 |
| `to_leftmost()` | 无 | 滚动到最左边,垂直位置不变 |
| `to_location(x, y)` | 滚动条坐标值 | 滚动到指定位置 |
| `up(pixel)` | 滚动的像素 | 向上滚动若干像素,水平位置不变 |
| `down(pixel)` | 滚动的像素 | 向下滚动若干像素,水平位置不变 |
| `right(pixel)` | 滚动的像素 | 向左滚动若干像素,垂直位置不变 |
| `left(pixel)` | 滚动的像素 | 向右滚动若干像素,垂直位置不变 |
```python
# 滚动到底部
ele.scroll.to_bottom()
# 滚动到最右边
ele.scroll.to_rightmost()
# 向下滚动 200 像素
ele.scroll.down(200)
# 滚动到指定位置
ele.scroll.to_location(100, 300)
```
# ✔️ 列表选择
## 📍 `select`
此属性用于对`<select>`元素的操作。非`<select>`元素此属性为`None`
调用此属性时返回一个`ChromiumSelect`对象,调用该对象的方法实现列表项的选中与取消。
假设有以下`<select>`元素,下面示例以此为基础:
```html
<select id='s' multiple>
<option value='value1'>text1</option>
<option value='value2'>text2</option>
<option value='value3'>text3</option>
</select>
```
该对象实现了`__call__()`方法,可直接调用进行按文本选择项目。
```python
ele = page.ele('#s')
ele.select('text1') # 选中文本为 'text1' 的项目
```
## 📍 方法
| 方法 | 参数说明 | 功能 |
|:---------------------------------:|:-------:|:--------------:|
| `by_text(text, timeout)` | 文本,超时时间 | 根据文本选择项 |
| `by_value(value, timeout)` | 项值,超时时间 | 根据值选择项 |
| `by_index(index, timeout)` | 序号,超时时间 | 根据序号选择项0开始 |
| `cancel_by_text(text, timeout)` | 文本,超时时间 | 根据文本取消选择(多选列表) |
| `cancel_by_value(value, timeout)` | 项值,超时时间 | 根据项值取消选择(多选列表) |
| `cancel_by_index(index, timeout)` | 序号,超时时间 | 根据序号取消选择(多选列表) |
| `invert()` | 无 | 反选(多选列表) |
| `clear()` | 无 | 清空列表(多选列表) |
```python
ele.select.by_text('text1') # 和 ele.select('text1') 一样
ele.select.by_value('value2') # 选中 value 属性为 'value2' 的项
ele.select.by_index(2) # 选中第 3 项
ele.select.cancel_by_text('text1') # 取消选中文本为 'text1' 的项
ele.select.cancel_by_value('value2') # 取消选中 value 属性为 'value2' 的项
ele.select.cancel_by_index(2) # 取消选中第 3 项
ele.invert() # 反选
ele.clear() # 清空
```
## 📍 属性
| 属性 | 说明 |
| ------------------ | --------------------- |
| `is_multi` | 返回是否多选表单 |
| `options` | 返回所有选项元素组成的列表 |
| `selected_option` | 返回第一个被选中的option元素 |
| `selected_options` | 返回所有被选中的option元素组成的列表 |
## 📍 多选
上述各种选择/取消选择的方法均支持多选下拉列表。
要选择/取消选择多项,只要传入相应内容组成的`tuple``list`即可。
```python
# 选择多个文本项
ele.select(('text1', 'text2'))
# 选择多个值
ele.select.by_value(('value1', 'value2'))
# 取消选择多个序号
ele.select.cancel_by_index((0, 2))
```
## 📍 等待
很多网站下拉列表采用 js 加载,如果加载不及时会导致异常。
因此本库在此集成了一个贴心小功能,上面各种方法均设置了`timeout`参数,如果选择目标未找到,会在限时内等待该项出现,超时就返回`False`
```python
# 目标选择 'abc',设置超时时间为 3 秒
result = ele.select('abc', 3)
# 输出:
False
```