mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
修改文档
This commit is contained in:
parent
8784f7dd48
commit
04db1f4408
@ -336,9 +336,9 @@ d 模式时检查网页是否符合预期。默认由 response 状态检查,
|
||||
|
||||
返回: None
|
||||
|
||||
## to_iframe()
|
||||
## to_frame()
|
||||
|
||||
跳转到 iframe,默认跳转到最高层级,兼容 selenium 原生参数。
|
||||
跳转到 frame,默认跳转到最高层级,兼容 selenium 原生参数。
|
||||
|
||||
参数说明:
|
||||
|
||||
@ -355,7 +355,7 @@ d 模式时检查网页是否符合预期。默认由 response 状态检查,
|
||||
- to_iframe('main') - 跳到最高层
|
||||
- to_iframe('parent') - 跳到上一层
|
||||
|
||||
返回: None
|
||||
返回: 自己,用于链式操作进行下一步元素查找
|
||||
|
||||
## scroll_to_see()
|
||||
|
||||
|
@ -2,6 +2,62 @@
|
||||
|
||||
d 模式下的 DriverElement 对象可以对浏览器相应元素进行控制。
|
||||
|
||||
# 一览表
|
||||
|
||||
以下为元素操作方法一览表,然后再详细介绍每个方法。
|
||||
|
||||
```python
|
||||
# 点击元素
|
||||
click()
|
||||
|
||||
# 带偏移量的点击元素
|
||||
click_at(x, y)
|
||||
|
||||
# 右键单击元素
|
||||
r_click()
|
||||
|
||||
# 带偏移量的右键单击元素
|
||||
r_click_at(x, y)
|
||||
|
||||
# 输入内容到元素
|
||||
input('...')
|
||||
|
||||
# 对元素执行 js 脚本
|
||||
run_script('...')
|
||||
|
||||
# 清空元素
|
||||
clear()
|
||||
|
||||
# 对元素截图
|
||||
screenshot()
|
||||
|
||||
# 设置元素某个 property 属性值
|
||||
set_prop('prop', 'value')
|
||||
|
||||
# 设置元素某个 attribute 属性值
|
||||
set_attr('attr', 'value')
|
||||
|
||||
# 删除元素某个 attribute 属性
|
||||
remove_attr('attr')
|
||||
|
||||
# 提交表单
|
||||
submit()
|
||||
|
||||
# 按偏移量拖拽元素
|
||||
drag(x, y)
|
||||
|
||||
# 拖拽元素到某个元素或坐标
|
||||
drag_to(other_ele_or_location)
|
||||
|
||||
# 在元素上悬停鼠标,可带偏移量
|
||||
hover(x, y)
|
||||
|
||||
# 执行下来列表操作,详见下面 Select 类部分
|
||||
select
|
||||
```
|
||||
|
||||
# 元素操作方法
|
||||
|
||||
## click()
|
||||
|
||||
此方法用于点击元素。可以选择是否用 js 方式点击,可以在点击失败时自动重试。默认情况下,使用 selenium 原生的点击方法,如果重试超过限定时间,自动改用 js 方式点击。可通过 by_js 参数设置点击方式。
|
||||
@ -30,6 +86,8 @@ ele.click(timeout = 10) # 不断重试点击,直到遮罩层消失,或到
|
||||
ele.click(by_js=True) # 无视遮罩层,直接用 js 点击下方元素
|
||||
```
|
||||
|
||||
|
||||
|
||||
## click_at()
|
||||
|
||||
此方法用于带偏移量点击元素,偏移量相对于元素左上角坐标。不传入x或y值时点击元素中点。可选择是否用 js 方式点击,但不会进行重试。
|
||||
@ -287,7 +345,7 @@ select 元素的操作较为复杂,因此专门做了一个类用于处理它
|
||||
select 元素要操作列表时,实际上是对这个 Select 对象进行操作。
|
||||
|
||||
```python
|
||||
ele.select # 元素对象的 select 属性
|
||||
ele.select
|
||||
```
|
||||
|
||||
## 属性
|
||||
|
@ -31,6 +31,89 @@ a 车载应用 https://gitee.com/explore/vehicle
|
||||
"""
|
||||
```
|
||||
|
||||
# 一览表
|
||||
|
||||
以下为元素信息一览表,然后再详细介绍每个信息。
|
||||
|
||||
```python
|
||||
# ============ 基本属性(DriverElement 和 SessionElement 都拥有)============
|
||||
# 元素 html 文本
|
||||
html
|
||||
|
||||
# 元素内部 html 文本
|
||||
inner_html
|
||||
|
||||
# 元素标签名
|
||||
tag
|
||||
|
||||
# 元素内部经格式化的文本
|
||||
text
|
||||
|
||||
# 元素内部未经格式化的文本
|
||||
raw_text
|
||||
|
||||
# 元素内所有文本节点组成的列表
|
||||
texts()
|
||||
|
||||
# 元素内部所有注释组成的列表
|
||||
comments
|
||||
|
||||
# 元素所有属性值
|
||||
attrs
|
||||
|
||||
# 元素某个属性值
|
||||
attr('...')
|
||||
|
||||
# 元素 href 或 src 属性
|
||||
link
|
||||
|
||||
# 元素所在页面对象
|
||||
page
|
||||
|
||||
# 元素内包装的真正执行功能的元素对象
|
||||
inner_ele
|
||||
|
||||
# 元素绝对 xpath 路径
|
||||
xpath
|
||||
|
||||
# 元素绝对 css selector 路径
|
||||
css_path
|
||||
|
||||
# 元素可用性
|
||||
is_valid()
|
||||
|
||||
# ============ DriverElement 独有属性 ============
|
||||
# 元素尺寸
|
||||
size
|
||||
|
||||
# 元素在页面上的位置
|
||||
location
|
||||
|
||||
# 元素的 before 伪元素内容
|
||||
before
|
||||
|
||||
# 元素的 after 伪元素内容
|
||||
after
|
||||
|
||||
# 获取元素某个 css 样式属性的方法
|
||||
style('...')
|
||||
|
||||
# 获取元素某个 property 属性值的方面
|
||||
prop('...')
|
||||
|
||||
# 元素处理下来列表的 Select 对象,仅 select 元素可用
|
||||
select
|
||||
|
||||
# 元素是否别选中
|
||||
is_select()
|
||||
|
||||
# 元素是否生效
|
||||
is_enablede()
|
||||
|
||||
# 元素是否显示
|
||||
is_displayed()
|
||||
```
|
||||
|
||||
# 基本属性
|
||||
|
||||
假设 ele 为以下 div 元素的对象:
|
||||
@ -42,6 +125,8 @@ a 车载应用 https://gitee.com/explore/vehicle
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## html
|
||||
|
||||
此属性返回元素的 outerHTML 文本。
|
||||
@ -56,6 +141,8 @@ html = ele.html
|
||||
"""
|
||||
```
|
||||
|
||||
|
||||
|
||||
## inner_html
|
||||
|
||||
此属性返回元素的 innerHTML 文本。
|
||||
@ -69,6 +156,8 @@ Hello World!
|
||||
"""
|
||||
```
|
||||
|
||||
|
||||
|
||||
## tag
|
||||
|
||||
此属性返回元素的标签名。
|
||||
@ -177,8 +266,10 @@ d 模式包装的是一个 selenium 的 WebElement 对象,s 模式包装的是
|
||||
获取该对象,可直接使用该对象以该库的原生代码来执行须要的操作,便于不同项目的对接,及使用本库没有封装的功能。
|
||||
|
||||
```python
|
||||
# 获取元素的 WebElement 对象
|
||||
web_ele = ele.inner_ele
|
||||
web_ele.find_element(By.ID, 'ele_id').click() # 使用 selenium 原生的元素点击方法
|
||||
# 使用 selenium 原生的元素点击方法
|
||||
web_ele.find_element(By.ID, 'ele_id').click()
|
||||
```
|
||||
|
||||
## xpath
|
||||
@ -186,7 +277,8 @@ web_ele.find_element(By.ID, 'ele_id').click() # 使用 selenium 原生的元素
|
||||
此属性返回当前元素在页面中 xpath 的绝对路径。
|
||||
|
||||
```python
|
||||
xpath = ele.xpath # 返回:/html/body/div
|
||||
xpath = ele.xpath
|
||||
# 返回:/html/body/div
|
||||
```
|
||||
|
||||
## css_path
|
||||
@ -194,7 +286,8 @@ xpath = ele.xpath # 返回:/html/body/div
|
||||
此属性返回当前元素在页面中 css selector 的绝对路径。
|
||||
|
||||
```python
|
||||
css = ele.css_path # 返回::nth-child(1)>:nth-child(1)>:nth-child(1)
|
||||
css = ele.css_path
|
||||
# 返回::nth-child(1)>:nth-child(1)>:nth-child(1)
|
||||
```
|
||||
|
||||
## is_valid()
|
||||
|
@ -2,22 +2,14 @@
|
||||
|
||||
本节介绍如何从页面对象或元素对象中获取须要的元素对象。
|
||||
|
||||
页面对象(MixPage)和元素对象(DriverElement 或 SessionElement)都可通过 ele()、eles()、s_ele()、s_eles()方法定位到其后代元素。DriverElement 还有专门用于获取
|
||||
shadow-root 的 shadow_root 属性。获取到的元素可继续用这些方法获取后代元素,支持链式操作。
|
||||
页面对象(MixPage)和元素对象(DriverElement 或 SessionElement)都可通过 ele()、eles()、s_ele()、s_eles()方法定位到其后代元素。
|
||||
DriverElement 还有专门用于获取shadow-root 的 shadow_root 属性。获取到的元素可继续用这些方法获取后代元素,支持链式操作。
|
||||
|
||||
除了以上方法,元素还有 next、prev、parent、nexts()、prevs()、parents() 等相对定位方法。
|
||||
|
||||
d 模式获取元素的方法内置了等待,默认使用元素所属页面的超时设置,也可用在每次获取元素时单独设置等待时间。
|
||||
|
||||
看一个例子,用显性等待方式定位第一个文本包含 some text 的元素。可以看出本库的定位语法比 selenium 做了大幅度精简,而且功能更强大:
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
element = WebDriverWait(driver).until(ec.presence_of_element_located((By.XPATH, '//*[contains(text(), "some text")]')))
|
||||
|
||||
# 使用 DrissionPage:
|
||||
element = page('some text')
|
||||
```
|
||||
|
||||
## 简单示例:
|
||||
|
||||
@ -39,19 +31,27 @@ element = page('some text')
|
||||
假设 page 为以上页面的 MixPage 对象,我们可以用这些方法获取其中的元素:
|
||||
|
||||
```python
|
||||
div1 = page.ele('#one') # 获取 id 为 one 的元素
|
||||
# 获取 id 为 one 的元素
|
||||
div1 = page.ele('#one')
|
||||
|
||||
p_eles = div1.eles('tag:p') # 获取 div1 元素内所有 p 元素组成的列表
|
||||
# 获取 div1 元素内所有 p 元素组成的列表
|
||||
p_eles = div1.eles('tag:p')
|
||||
|
||||
row1 = page.ele('@name=row1') # 获取 name 属性为 row1 的元素
|
||||
# 获取 name 属性为 row1 的元素
|
||||
row1 = page.ele('@name=row1')
|
||||
|
||||
p_ele = page.ele('tag:p@@text():第二@@name=row2') # 获取 name 属性为 row2 且包含“第二”文本的 p 元素
|
||||
# 获取 name 属性为 row2 且包含“第二”文本的 p 元素
|
||||
p_ele = page.ele('tag:p@@text():第二@@name=row2')
|
||||
|
||||
div2 = page.ele('第二个div') # 获取包含“第二个div”文本的元素
|
||||
# 获取包含“第二个div”文本的元素
|
||||
div2 = page.ele('第二个div')
|
||||
|
||||
div2 = page.ele('x://div[@id="tow"]') # 用 xpath c
|
||||
# 用 xpath 查找
|
||||
div2 = page.ele('x://div[@id="tow"]')
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 实际示例:
|
||||
|
||||
```python
|
||||
@ -76,26 +76,78 @@ IOT/物联网/边缘计算
|
||||
"""
|
||||
```
|
||||
|
||||
# 方法和属性
|
||||
# 一览表
|
||||
|
||||
以下为获取元素方法一览表,然后再详细介绍每个方法。
|
||||
|
||||
```python
|
||||
# 在页面或元素内部查找一个元素
|
||||
ele1 = page.ele('...')
|
||||
ele2 = ele1.ele('...')
|
||||
|
||||
# 在页面或元素内部查找多个元素
|
||||
ele_list1 = page.eles('...')
|
||||
ele_list2 = ele1.eles('...')
|
||||
|
||||
# 在页面或元素内部查找一个元素并返回其 SessionElement 形式的对象
|
||||
ele1 = page.s_ele('...')
|
||||
ele2 = ele1.s_ele('...')
|
||||
|
||||
# 在页面或元素内部查找多个元素并返回它们的 SessionElement 形式的对象
|
||||
ele1 = page.s_eles('...')
|
||||
ele2 = ele1.s_eles('...')
|
||||
|
||||
# 获取元素后面一个兄弟元素
|
||||
ele2 = ele1.next
|
||||
|
||||
# 获取元素前面一个兄弟元素
|
||||
ele2 = ele1.prev
|
||||
|
||||
# 获取元素的父元素
|
||||
ele2 = ele1.parent
|
||||
|
||||
# 获取元素后面第 2 个兄弟元素
|
||||
ele2 = ele1.nexts(2)
|
||||
|
||||
# 获取元素前面第 2 个兄弟元素
|
||||
ele2 = ele1.prevs(2)
|
||||
|
||||
# 获取元素的第 2 层父元素
|
||||
ele2 = ele1.parents(2)
|
||||
|
||||
# 获取元素内部的 shadow_root 并以 ShadowRootElement 对象返回
|
||||
ele_sr = shadow_root
|
||||
```
|
||||
|
||||
# 定位方法
|
||||
|
||||
## ele()
|
||||
|
||||
此方法用于查找并返回第一个匹配的元素,d 模式下返回 DriverElement,s 模式下返回 SessionElement,用 xpath 获取元素属性时,直接返回属性文本。查找不到结果则返回 None。
|
||||
|
||||
```python
|
||||
ele1 = page.ele('search text') # 在页面内查找元素
|
||||
ele2 = ele1.ele('search text') # 在元素内查找后代元素
|
||||
# 在页面内查找元素
|
||||
ele1 = page.ele('search text')
|
||||
|
||||
# 在元素内查找后代元素
|
||||
ele2 = ele1.ele('search text')
|
||||
```
|
||||
|
||||
|
||||
|
||||
## eles()
|
||||
|
||||
此方法与 ele() 相似,但返回的是匹配到的所有元素组成的列表,用 xpath 获取元素属性时,返回属性文本组成的列表。
|
||||
|
||||
```python
|
||||
p_eles = ele.eles('tag:p') # 获取 ele 元素内的所有 p 元素
|
||||
p1 = p_eles[0] # 获取第一个 p 元素
|
||||
# 获取 ele 元素内的所有 p 元素
|
||||
p_eles = ele.eles('tag:p')
|
||||
# 打印第一个 p 元素
|
||||
print(p_eles[0])
|
||||
```
|
||||
|
||||
|
||||
|
||||
## s_ele()
|
||||
|
||||
此方法用于在一个元素下查找后代元素,以 SessionElement 形式返回结果(xpath 获取属性值时依然是返回 str),也可以直接将一个元素转换为 SessionElement 版本。
|
||||
@ -105,33 +157,42 @@ p1 = p_eles[0] # 获取第一个 p 元素
|
||||
s 模式下这个方法和 ele() 是一样的。
|
||||
|
||||
```python
|
||||
ele2 = ele1.s_ele() # 获取 ele1 元素的 SessionElement 版本
|
||||
# 获取 ele1 元素的 SessionElement 版本
|
||||
ele2 = ele1.s_ele()
|
||||
|
||||
ele2 = ele1.s_ele('search text') # 在 ele1 元素下查找元素,并以 SessionElemnet 返回
|
||||
# 在 ele1 元素下查找元素,并以 SessionElemnet 返回
|
||||
ele2 = ele1.s_ele('search text')
|
||||
|
||||
ele = page.s_ele('search text') # 在页面下查找元素,并以 SessionElemnet 返回
|
||||
# 在页面下查找元素,并以 SessionElemnet 返回
|
||||
ele = page.s_ele('search text')
|
||||
```
|
||||
|
||||
## s_eles()
|
||||
|
||||
此方法与 s_ele() 相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。
|
||||
此方法与 s_ele() 相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。页面对象没有此方法。
|
||||
|
||||
## next
|
||||
|
||||
此属性返回当前元素的后一个兄弟元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.next # 获取 ele1 后面一个兄弟元素
|
||||
# 获取 ele1 后面一个兄弟元素
|
||||
ele2 = ele1.next
|
||||
```
|
||||
|
||||
|
||||
|
||||
## prev
|
||||
|
||||
此属性返回当前元素的前一个兄弟元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.prev # 获取 ele1 前面一个兄弟元素
|
||||
# 获取 ele1 前面一个兄弟元素
|
||||
ele2 = ele1.prev
|
||||
```
|
||||
|
||||
|
||||
|
||||
## parent
|
||||
|
||||
此属性返回当前元素的父元素。
|
||||
@ -139,33 +200,45 @@ ele2 = ele1.prev # 获取 ele1 前面一个兄弟元素
|
||||
注:ShadowRootElement 的这个属性返回其所属元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.parent # 获取 ele1 的父元素
|
||||
# 获取 ele1 的父元素
|
||||
ele2 = ele1.parent
|
||||
```
|
||||
|
||||
|
||||
|
||||
## nexts()
|
||||
|
||||
此方法返回当前元素后面第若干个兄弟元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.nexts(3) # 获取 ele1 后面第三个兄弟元素
|
||||
# 获取 ele1 后面第三个兄弟元素
|
||||
ele2 = ele1.nexts(3)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## prevs()
|
||||
|
||||
此方法返回当前元素前面第若干个兄弟元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.prevs(3) # 获取 ele1 前面第三个兄弟元素
|
||||
# 获取 ele1 前面第三个兄弟元素
|
||||
ele2 = ele1.prevs(3)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## parents()
|
||||
|
||||
此方法返回当前元素第若干层祖先元素。
|
||||
|
||||
```python
|
||||
ele2 = ele1.parents(3) # 获取 ele1 上面 3 层父元素
|
||||
# 获取 ele1 上面 3 层父元素
|
||||
ele2 = ele1.parents(3)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## shadow_root
|
||||
|
||||
DriverElement 元素除了以上方法和属性外,还有 shadow_root 属性,用于获取其内部的 shadow_root 元素。
|
||||
@ -173,21 +246,28 @@ DriverElement 元素除了以上方法和属性外,还有 shadow_root 属性
|
||||
该 DriverElement 和普通的没有区别。
|
||||
|
||||
```python
|
||||
shadow_ele = ele.shadow_root # 获取一个元素下是 shadow root
|
||||
ele1 = shadow_ele.ele('search text') # 获取该 shadow root 下的一个元素
|
||||
ele1.click() # 点击获取到的元素
|
||||
# 获取一个元素下是 shadow root
|
||||
shadow_ele = ele.shadow_root
|
||||
# 获取该 shadow root 下的一个元素
|
||||
ele1 = shadow_ele.ele('search text')
|
||||
# 点击获取到的元素
|
||||
ele1.click()
|
||||
```
|
||||
|
||||
# 定位语法
|
||||
## active_ele
|
||||
|
||||
该属性返回当前页面焦点所在元素。
|
||||
|
||||
```python
|
||||
ele = page.active_ele
|
||||
```
|
||||
|
||||
# 查找语法
|
||||
|
||||
我们使用一套简洁高效的语法去定位元素,大大简化了定位元素的代码量,增强了功能,也兼容 css selector、xpath、selenium 原生的 loc 元组(s 模式也能用)。d 模式和 s
|
||||
模式定位元素的语法是完全一样的,便于模式切换时平滑过渡。
|
||||
|
||||
|
||||
|
||||
## 关键字
|
||||
|
||||
关键字是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
|
||||
**关键字** 是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
|
||||
|
||||
## =
|
||||
|
||||
@ -197,14 +277,18 @@ ele1.click() # 点击获取到的元素
|
||||
|
||||
表示模糊匹配,匹配含有某个字符串的文本或属性。
|
||||
|
||||
|
||||
|
||||
## \#
|
||||
|
||||
表示 id 属性,只在语句最前面且单独使用时生效,可配合 = 或 :。
|
||||
|
||||
```python
|
||||
ele1 = page.ele('#ele_id') # 在页面中查找 id 属性为 ele_id 的元素
|
||||
# 在页面中查找 id 属性为 ele_id 的元素
|
||||
ele1 = page.ele('#ele_id')
|
||||
|
||||
ele2 = ele1.ele('#:ele_id') # 在 ele1 元素内查找 id 属性包含 ele_id 文本的元素
|
||||
# 在 ele1 元素内查找 id 属性包含 ele_id 文本的元素
|
||||
ele2 = ele1.ele('#:ele_id')
|
||||
```
|
||||
|
||||
## .
|
||||
@ -212,33 +296,59 @@ ele2 = ele1.ele('#:ele_id') # 在 ele1 元素内查找 id 属性包含 ele_id
|
||||
表示 class 属性,只在语句最前面且单独使用时生效,可配合 = 或 :。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('.ele_class') # 查找 class 属性为 ele_class 的元素
|
||||
# 查找 class 属性为 ele_class 的元素
|
||||
ele2 = ele1.ele('.ele_class')
|
||||
|
||||
ele2 = ele1.ele('.:ele_class') # 查找 class 属性包含 ele_class 文本的元素
|
||||
# 查找 class 属性包含 ele_class 文本的元素
|
||||
ele2 = ele1.ele('.:ele_class')
|
||||
```
|
||||
|
||||
## @
|
||||
|
||||
表示某个属性,只匹配一个属性。
|
||||
表示某个属性,只匹配一个属性。
|
||||
@ 关键字只有一个简单功能,就是匹配 @ 后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在 @ 或 @@,也作为要匹配的内容对待。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('@name=ele_name') # 查找 name 属性为 ele_name 的元素
|
||||
# 查找 name 属性为 ele_name 的元素
|
||||
ele2 = ele1.ele('@name=ele_name')
|
||||
|
||||
ele2 = ele1.ele('@name:ele_name') # 查找 name 属性包含 ele_name 文本的元素
|
||||
# 查找 name 属性包含 ele_name 文本的元素
|
||||
ele2 = ele1.ele('@name:ele_name')
|
||||
|
||||
ele2 = ele1.ele('@name') # 查找有 name 属性的元素
|
||||
# 查找有 name 属性的元素
|
||||
ele2 = ele1.ele('@name')
|
||||
|
||||
ele2 = ele1.ele('@') # 查找没有任何属性的元素
|
||||
# 查找没有任何属性的元素
|
||||
ele2 = ele1.ele('@')
|
||||
|
||||
ele2 = ele1.ele('@email=abc@def.com') # 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理
|
||||
# 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理
|
||||
ele2 = ele1.ele('@email=abc@def.com')
|
||||
```
|
||||
|
||||
## @@
|
||||
|
||||
表示某个属性,多属性匹配时使用,个数不限。如匹配文本或属性中出现 @@,不能使用此方式,须改用 xpath的方式。
|
||||
表示某个属性,多属性匹配时使用,个数不限。还能匹配要忽略的元素,匹配文本时也和 @ 不一样。
|
||||
@@ 后跟 - 时,表示 not。如:
|
||||
|
||||
- `@@-name`表示匹配没有 name 属性的元素
|
||||
|
||||
- `@@-name=ele_name`表示匹配 name 属性不为 ele_name 的元素
|
||||
|
||||
如有以下情况,不能使用此方式,须改用 xpath的方式:
|
||||
|
||||
- 匹配文本或属性中出现 @@
|
||||
|
||||
- 属性名本身以 - 开头
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('@@name=name@@class:cls') # 查找 name 属性为 name 且 class 属性包含 cls 文本的元素
|
||||
# 查找 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
|
||||
@ -247,25 +357,42 @@ ele2 = ele1.ele('@@name=name@@class:cls') # 查找 name 属性为 name 且 clas
|
||||
如果元素内有多个直接的文本节点,精确查找时可匹配所有文本节点拼成的字符串,模糊查找时可匹配每个文本节点。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('text=some text') # 查找文本为 some text 的元素
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('text=some text')
|
||||
|
||||
ele2 = ele1.ele('text:some text') # 查找文本包含 some text 的元素
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('text:some text')
|
||||
|
||||
ele2 = ele1.ele('some text') # 与上一行一致
|
||||
# 与上一行一致
|
||||
ele2 = ele1.ele('some text')
|
||||
```
|
||||
|
||||
## text()
|
||||
|
||||
作为查找属性时使用的文本关键字,必须与 @ 或 @@ 配合使用。
|
||||
作为查找属性时使用的文本关键字,必须与 @ 或 @@ 配合使用。
|
||||
与 @ 配合和与 @@ 配合使用时,text() 的意义是有差别的。
|
||||
|
||||
@text() 表示在元素的直接子文本节点中匹配,且多个节点不能合并匹配。 @@text() 表示在元素内部所有文本中匹配,且会把元素内部所有文本拼成一个总字符串再进行匹配,因此可以模糊匹配元素里面任意文本。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('@text()=some text') # 查找文本为 some text 的元素
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('@text()=some text')
|
||||
|
||||
ele2 = ele1.ele('@text():some text') # 查找文本包含 some text 的元素
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('@text():some text')
|
||||
|
||||
ele2 = ele1.ele('@@text()=some text@@class=cls') # 查找文本为 some text 且 class 属性为 cls 的元素
|
||||
# 查找文本为 some text 且 class 属性为 cls 的元素
|
||||
ele2 = ele1.ele('@@text()=some text@@class=cls')
|
||||
|
||||
ele2 = ele1.ele('@@@@text():some text') # 查找文本为 some text 且没有任何属性的元素(因第一个 @@ 后为空)
|
||||
# 查找文本为 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')
|
||||
```
|
||||
|
||||
## tag
|
||||
@ -273,17 +400,23 @@ ele2 = ele1.ele('@@@@text():some text') # 查找文本为 some text 且没有
|
||||
表示元素的标签,只在语句最前面且单独使用时生效,可与 @ 或 @@ 配合使用。tag: 与 tag= 效果一致。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('tag:div') # 定位 div 元素
|
||||
# 定位 div 元素
|
||||
ele2 = ele1.ele('tag:div')
|
||||
|
||||
ele2 = ele1.ele('tag:div@class=cls') # 定位 class 属性为 cls 的 div 元素
|
||||
# 定位 class 属性为 cls 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@class=cls')
|
||||
|
||||
ele2 = ele1.ele('tag:div@text()=text') # 定位文本为 text 的 div 元素
|
||||
# 定位文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text()=text')
|
||||
|
||||
ele2 = ele1.ele('tag:div@@class=cls@@text()=text') # 定位 class 属性为 cls 且文本为 text 的 div 元素
|
||||
# 定位 class 属性为 cls 且文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@class=cls@@text()=text')
|
||||
|
||||
ele2 = ele1.ele('tag:div@text():text') # 查找直接文本节点包含 text 字符串的 div 元素
|
||||
# 查找直接文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text():text')
|
||||
|
||||
ele2 = ele1.ele('tag:div@@text():text') # 查找内部文本节点包含 text 字符串的 div 元素
|
||||
# 查找内部文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@text():text')
|
||||
```
|
||||
|
||||
**Tips:** 注意, `'tag:div@text():text'` 和 `'tag:div@@text():text'` 是有区别的,前者只在 div 的直接文本节点搜索,后者搜索 div 的整个内部。
|
||||
@ -293,9 +426,11 @@ ele2 = ele1.ele('tag:div@@text():text') # 查找内部文本节点包含 text
|
||||
表示用 css selector 方式查找元素。css: 与 css= 效果一致。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('css:.div') # 查找 div 元素
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('css:.div')
|
||||
|
||||
ele2 = ele1.ele('css:>div') # 查找 div 子元素元素,这个写法是本库特有,原生不支持
|
||||
# 查找 div 子元素元素,这个写法是本库特有,原生不支持
|
||||
ele2 = ele1.ele('css:>div')
|
||||
```
|
||||
|
||||
## xpath
|
||||
@ -304,11 +439,14 @@ ele2 = ele1.ele('css:>div') # 查找 div 子元素元素,这个写法是本
|
||||
该方法支持完整的 xpath 语法,能使用 xpath 直接获取元素属性,selenium 不支持这种用法。
|
||||
|
||||
```python
|
||||
ele2 = ele1.ele('xpath:.//div') # 查找 div 元素
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('xpath:.//div')
|
||||
|
||||
ele2 = ele1.ele('xpath://div') # 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
|
||||
# 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
|
||||
ele2 = ele1.ele('xpath://div')
|
||||
|
||||
txt = ele1.ele('xpath://div/@class') # 获取 div 元素的 class 属性,返回字符串
|
||||
# 获取 div 元素的 class 属性,返回字符串
|
||||
txt = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
@ -320,11 +458,13 @@ txt = ele1.ele('xpath://div/@class') # 获取 div 元素的 class 属性,返
|
||||
查找方法能直接接收 selenium 原生定位元组进行查找,s 模式下也支持这种写法。
|
||||
|
||||
```python
|
||||
# 查找 id 为 ele_id 的元素
|
||||
loc1 = By.ID, 'ele_id'
|
||||
ele = page.ele(loc1) # 查找 id 为 ele_id 的元素
|
||||
ele = page.ele(loc1)
|
||||
|
||||
# 按 xpath 查找
|
||||
loc2 = By.XPATH, '//div[@class="ele_class"]'
|
||||
ele = page.ele(loc2) # 按 xpath 查找
|
||||
ele = page.ele(loc2)
|
||||
```
|
||||
|
||||
# 等待
|
||||
@ -332,13 +472,19 @@ ele = page.ele(loc2) # 按 xpath 查找
|
||||
d 模式下所有查找元素操作都自带等待,默认为 10 秒,也可以在每次查找时单独设置。元素等待时间默认继承其所在页面时间。单独设置的等待时间不会改变页面原来设置。
|
||||
|
||||
```python
|
||||
page = MixPage(timeout=15) # 页面初始化时设置查找元素超时时间为 15 秒
|
||||
page.timeout = 5 # 设置查找元素超时时间为 5 秒
|
||||
# 页面初始化时设置查找元素超时时间为 15 秒
|
||||
page = MixPage(timeout=15)
|
||||
# 设置查找元素超时时间为 5 秒
|
||||
page.timeout = 5
|
||||
|
||||
ele1 = page.ele('some text') # 使用页面超时时间来查找元素(5 秒)
|
||||
ele1 = page.ele('some text', timeout=1) # 为这次查找页面独立设置等待时间(1 秒)
|
||||
ele2 = ele1.ele('some text') # 查找后代元素,使用页面超时时间(5 秒)
|
||||
ele2 = ele1.ele('some text', timeout=1) # 查找后代元素,使用单独设置的超时时间(1 秒)
|
||||
# 使用页面超时时间来查找元素(5 秒)
|
||||
ele1 = page.ele('some text')
|
||||
# 为这次查找页面独立设置等待时间(1 秒)
|
||||
ele1 = page.ele('some text', timeout=1)
|
||||
# 查找后代元素,使用页面超时时间(5 秒)
|
||||
ele2 = ele1.ele('some text')
|
||||
# 查找后代元素,使用单独设置的超时时间(1 秒)
|
||||
ele2 = ele1.ele('some text', timeout=1)
|
||||
```
|
||||
|
||||
# 简化写法
|
||||
@ -352,13 +498,17 @@ ele2 = ele1.ele('some text', timeout=1) # 查找后代元素,使用单独设
|
||||
示例:
|
||||
|
||||
```python
|
||||
eles = page('#table_id').eles('t:tr') # 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
eles = page('#table_id').eles('t:tr')
|
||||
|
||||
ele2 = ele1('.cls1')('tx=text') # 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
ele2 = ele1('.cls1')('tx=text')
|
||||
|
||||
ele2 = ele1.sr('.cls') # 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
ele2 = ele1.sr('.cls')
|
||||
|
||||
ele2 = ele1('x://div[@class="ele_class"]') # 按xpath 查找元素
|
||||
# 按xpath 查找元素
|
||||
ele2 = ele1('x://div[@class="ele_class"]')
|
||||
```
|
||||
|
||||
简化写法对应列表
|
||||
|
@ -1,9 +0,0 @@
|
||||
- 以简洁的代码为第一追求。
|
||||
- 允许在 selenium 和 requests 间无缝切换,共享 session。
|
||||
- 两种模式提供一致的 API,使用体验一致。
|
||||
- 人性化的页面元素操作方式,减轻页面分析工作量和编码量。
|
||||
- 对常用功能作了整合和优化,更符合实际使用需要。
|
||||
- 兼容 selenium 代码,便于项目迁移。
|
||||
- 使用 POM 模式封装,便于扩展。
|
||||
- 统一的文件下载方法,弥补浏览器下载的不足。
|
||||
- 简易的配置方法,摆脱繁琐的浏览器配置。
|
62
docs/简介.md
62
docs/简介.md
@ -2,10 +2,10 @@
|
||||
|
||||
DrissionPage,即 driver 和 session 组合而成的 page。
|
||||
是个基于 python 的 Web 自动化操作集成工具。
|
||||
它实现了 selenium 和 requests 之间的无缝切换。
|
||||
可以兼顾 selenium 的便利性和 requests 的高效率。
|
||||
它集成了页面常用功能,两种模式系统一致的 API,使用便捷。
|
||||
它用 POM 模式封装了页面元素常用的方法,适合自动化操作功能扩展。
|
||||
它用 POM 模式封装了页面和元素常用的方法,
|
||||
自带一套简洁直观优雅的元素定位语法,
|
||||
实现了 selenium 和 requests 之间的无缝切换,
|
||||
可兼顾 selenium 的便利性和 requests 的高效率,
|
||||
更棒的是,它的使用方式非常简洁和人性化,代码量少,对新手友好。
|
||||
|
||||
**项目地址:**
|
||||
@ -15,21 +15,49 @@ DrissionPage,即 driver 和 session 组合而成的 page。
|
||||
|
||||
**示例地址:** [使用DrissionPage的网页自动化及爬虫示例](https://gitee.com/g1879/DrissionPage-demos)
|
||||
|
||||
**联系邮箱:** g1879@qq.com
|
||||
|
||||
**QQ交流群:** 897838127
|
||||
|
||||
***
|
||||
|
||||
# 理念
|
||||
|
||||
**简洁、易用 、可扩展**
|
||||
|
||||
***
|
||||
**联系邮箱:** g1879@qq.com **QQ交流群:** 897838127
|
||||
|
||||
# 背景
|
||||
|
||||
requests 爬虫面对要登录的网站时,要分析数据包、JS 源码,构造复杂的请求,往往还要应付验证码、JS 混淆、签名参数等反爬手段,门槛较高。若数据是由 JS 计算生成的,还须重现计算过程,体验不好,开发效率不高。
|
||||
使用 selenium,可以很大程度上绕过这些坑,但 selenium 效率不高。因此,这个库将 selenium 和 requests 合而为一,不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
|
||||
除了合并两者,本库还以网页为单位封装了常用功能,简化了 selenium 的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。
|
||||
一切从简,尽量提供简单直接的使用方法,对新手更友好。
|
||||
除了合并两者,本库还以网页为单位封装了常用功能,简化了 selenium 的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。
|
||||
|
||||
# 特性
|
||||
|
||||
- 代码高度集成,以简洁的代码为第一追求。
|
||||
- 页面对象可在 selenium 和 requests 模式间任意切换,保留登录状态。
|
||||
- 极简单但强大的元素定位语法,支持链式操作,代码极其简洁。
|
||||
- 两种模式提供一致的 API,使用体验一致。
|
||||
- 使用 POM 模式封装,便于扩展。
|
||||
- 兼容 selenium 代码,便于项目迁移。
|
||||
- 人性化设计,集成众多实用功能,大大降低开发工作量。
|
||||
|
||||
# 亮点功能
|
||||
|
||||
作者有多年自动化和爬虫经验,踩过无数坑,总结出的经验全写到这个库里。内置了N多实用功能,对常用功能作了整合和优化。使用时可以更专注业务逻辑,减少重复操作。大概罗列一下:
|
||||
|
||||
- 每次运行程序可以反复使用已经打开的浏览器。如手动设置网页到某个状态,再用程序接管,或手动处理登录,再用程序爬内容。无须每次运行从头启动浏览器,超级方便。
|
||||
- 使用 ini 文件保存常用配置,自动调用,也提供便捷的设置api,远离繁杂的配置项。
|
||||
- 极致简明的定位语法,支持直接按文本定位元素,支持直接获取前后兄弟元素和父元素等。
|
||||
- 强大的下载工具,操作浏览器时也能享受快捷可靠的下载功能。
|
||||
- 下载工具支持多种方式处理文件名冲突、自动创建目标路径、断链重试等。
|
||||
- 访问网址带自动重试功能,可设置间隔和超时时间。
|
||||
- 访问网页能自动识别编码,无须手动设置。
|
||||
- 链接参数默认自动生成 Host 和 Referer 属性。
|
||||
- 可随时直接隐藏或显示浏览器进程窗口,非 headless 或最小化。
|
||||
- 可自动下载合适版本的 chromedriver,免去麻烦的配置。
|
||||
- d 模式查找元素内置等待,可任意设置全局等待时间或单次查找等待时间。
|
||||
- 点击元素集成 js 点击方式,一个参数即可切换点击方式。
|
||||
- 点击支持失败重试,可用于保证点击成功、判读网页遮罩层是否消失等。
|
||||
- 输入文本能自动判断是否成功并重试,避免某些情况下输入或清空失效的情况。
|
||||
- d 模式下支持全功能的 xpath,可直接获取元素的某个属性,selenium 原生无此功能。
|
||||
- 支持直接获取 shadow-root,和普通元素一样操作其下的元素。
|
||||
- 支持直接获取 after 和 before 伪元素的内容。
|
||||
- 可以在元素下直接使用 > 以 css selector 方式获取当前元素直接子元素。原生不支持这种写法。
|
||||
- 可简单地使用 lxml 来解析 d 模式的页面或元素,爬取复杂页面数据时速度大幅提高。
|
||||
- 输出的数据均已转码及处理基本排版,减少重复劳动。
|
||||
- 可方便地与 selenium 或 requests 原生代码对接,便于项目迁移。
|
||||
- 使用 POM 模式封装,可直接用于测试,便于扩展。
|
||||
- d 模式配置可同时兼容 debugger 和其它参数,原生不能兼容。
|
||||
- 还有很多这里不一一列举…………
|
||||
|
Loading…
x
Reference in New Issue
Block a user