mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
修复点击圆形控件不准问题;修复一个位置数据类型;继续修改ChromiumFrame;修改文档
This commit is contained in:
parent
51cb918b32
commit
57273ca79d
@ -13,3 +13,4 @@ from .chromium_page import ChromiumPage
|
||||
from .session_page import SessionPage
|
||||
from .drission import Drission
|
||||
from .config import DriverOptions, SessionOptions
|
||||
from .action_chains import ActionChains
|
||||
|
@ -156,7 +156,7 @@ class ChromiumElement(DrissionElement):
|
||||
def _client_click_point(self):
|
||||
"""返回元素左上角可接受点击的点视口坐标"""
|
||||
m = self._get_client_rect('padding')
|
||||
return (m[0], m[1]) if m else (0, 0)
|
||||
return (self.client_midpoint[0], m[1]) if m else (0, 0)
|
||||
|
||||
@property
|
||||
def _click_point(self):
|
||||
@ -664,7 +664,7 @@ class ChromiumElement(DrissionElement):
|
||||
"""实施点击 \n
|
||||
:param client_x: 视口中的x坐标
|
||||
:param client_y: 视口中的y坐标
|
||||
:param button: 'left'或'right'
|
||||
:param button: 'left' 或 'right'
|
||||
:return: None
|
||||
"""
|
||||
self.page.driver.Input.dispatchMouseEvent(type='mousePressed', x=client_x, y=client_y, button=button,
|
||||
@ -1385,17 +1385,17 @@ def _offset_scroll(ele, offset_x, offset_y):
|
||||
:param offset_y: 偏移量y
|
||||
:return: 视口中的坐标
|
||||
"""
|
||||
location = ele.location
|
||||
midpoint = ele._click_point
|
||||
lx = location['x'] + offset_x if offset_x else midpoint['x']
|
||||
ly = location['y'] + offset_y if offset_y else midpoint['y']
|
||||
loc_x, loc_y = ele.location
|
||||
cp_x, cp_y = ele._click_point
|
||||
lx = loc_x + offset_x if offset_x else cp_x
|
||||
ly = loc_y + offset_y if offset_y else cp_y
|
||||
|
||||
if not _location_in_viewport(ele.page, lx, ly):
|
||||
ele.page.scroll.to_location(lx, ly)
|
||||
cl = ele.client_location
|
||||
cm = ele._client_click_point
|
||||
cx = cl['x'] + offset_x if offset_x else cm['x']
|
||||
cy = cl['y'] + offset_y if offset_y else cm['y']
|
||||
cl_x, cl_y = ele.client_location
|
||||
ccp_x, ccp_y = ele._client_click_point
|
||||
cx = cl_x + offset_x if offset_x else ccp_x
|
||||
cy = cl_y + offset_y if offset_y else ccp_y
|
||||
return cx, cy
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ from .chromium_element import ChromiumElement
|
||||
class ChromiumFrame(ChromiumBase):
|
||||
def __init__(self, page, ele):
|
||||
self.page = page
|
||||
self.address = self.page.address
|
||||
self.address = page.address
|
||||
node = page.run_cdp('DOM.describeNode', nodeId=ele.node_id, not_change=True)['node']
|
||||
self.frame_id = node['frameId']
|
||||
self._backend_id = ele.backend_id
|
||||
@ -48,18 +48,25 @@ class ChromiumFrame(ChromiumBase):
|
||||
node = self.page.run_cdp('DOM.describeNode', nodeId=self._frame_ele.node_id, not_change=True)['node']
|
||||
|
||||
if self._is_inner_frame():
|
||||
print('-111')
|
||||
self._is_diff_domain = False
|
||||
self.doc_ele = ChromiumElement(self.page, backend_id=node['contentDocument']['backendNodeId'])
|
||||
super().__init__(self.address, self.page.tab_id, self.page.timeout)
|
||||
print('+111')
|
||||
else:
|
||||
print('-222')
|
||||
self._is_diff_domain = True
|
||||
self._tab_obj.stop()
|
||||
super().__init__(self.address, self.frame_id, self.page.timeout)
|
||||
obj_id = super().run_script('document;', as_expr=True)['objectId']
|
||||
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
||||
print('+222')
|
||||
|
||||
def _check_ok(self):
|
||||
if self._tab_obj._stopped.is_set():
|
||||
self._reload()
|
||||
|
||||
try:
|
||||
self._tab_obj.DOM.describeNode(nodeId=self.node_id)
|
||||
except:
|
||||
self._reload()
|
||||
sleep(2)
|
||||
|
||||
def _get_new_document(self):
|
||||
"""刷新cdp使用的document数据"""
|
||||
@ -94,7 +101,6 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
def _onFrameStartedLoading(self, **kwargs):
|
||||
"""页面开始加载时触发"""
|
||||
# print('开始', kwargs['frameId'])
|
||||
if kwargs['frameId'] == self.frame_id:
|
||||
self._is_loading = True
|
||||
if self._debug:
|
||||
@ -102,7 +108,6 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
def _onFrameStoppedLoading(self, **kwargs):
|
||||
"""页面加载完成后触发"""
|
||||
# print('停止', kwargs['frameId'])
|
||||
if kwargs['frameId'] == self.frame_id and self._first_run is False and self._is_loading:
|
||||
if self._debug:
|
||||
print('页面停止加载 FrameStoppedLoading')
|
||||
@ -136,16 +141,19 @@ class ChromiumFrame(ChromiumBase):
|
||||
@property
|
||||
def tag(self):
|
||||
"""返回元素tag"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.tag
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
"""返回frame当前访问的url"""
|
||||
self._check_ok()
|
||||
return self.doc_ele.run_script('return this.location.href;')
|
||||
|
||||
@property
|
||||
def html(self):
|
||||
"""返回元素outerHTML文本"""
|
||||
self._check_ok()
|
||||
tag = self.tag
|
||||
out_html = self.page.run_cdp('DOM.getOuterHTML',
|
||||
nodeId=self.frame_ele.node_id, not_change=True)['outerHTML']
|
||||
@ -155,30 +163,31 @@ class ChromiumFrame(ChromiumBase):
|
||||
@property
|
||||
def inner_html(self):
|
||||
"""返回元素innerHTML文本"""
|
||||
self._check_ok()
|
||||
return self.doc_ele.run_script('return this.documentElement.outerHTML;')
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
"""返回页面title"""
|
||||
while True:
|
||||
try:
|
||||
self._check_ok()
|
||||
return self.ele('t:title').text
|
||||
except:
|
||||
self._reload()
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
"""以dict格式返回cookies"""
|
||||
self._check_ok()
|
||||
return super().cookies if self._is_diff_domain else self.doc_ele.run_script('return this.cookie;')
|
||||
|
||||
@property
|
||||
def attrs(self):
|
||||
"""返回frame元素所有attribute属性"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.attrs
|
||||
|
||||
@property
|
||||
def frame_size(self):
|
||||
"""返回frame内页面尺寸,格式:(长, 高)"""
|
||||
self._check_ok()
|
||||
w = self.doc_ele.run_script('return this.body.scrollWidth')
|
||||
h = self.doc_ele.run_script('return this.body.scrollHeight')
|
||||
return w, h
|
||||
@ -186,31 +195,37 @@ class ChromiumFrame(ChromiumBase):
|
||||
@property
|
||||
def size(self):
|
||||
"""返回frame元素大小"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.size
|
||||
|
||||
@property
|
||||
def active_ele(self):
|
||||
"""返回当前焦点所在元素"""
|
||||
self._check_ok()
|
||||
return self.doc_ele.run_script('return this.activeElement;')
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回frame元素左上角的绝对坐标"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.location
|
||||
|
||||
@property
|
||||
def is_displayed(self):
|
||||
"""返回frame元素是否显示"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.is_displayed
|
||||
|
||||
@property
|
||||
def xpath(self):
|
||||
"""返回frame的xpath绝对路径"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.xpath
|
||||
|
||||
@property
|
||||
def css_path(self):
|
||||
"""返回frame的css selector绝对路径"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.css_path
|
||||
|
||||
@property
|
||||
@ -231,6 +246,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
def refresh(self):
|
||||
"""刷新frame页面"""
|
||||
self._check_ok()
|
||||
self.doc_ele.run_script('this.location.reload();')
|
||||
|
||||
def attr(self, attr):
|
||||
@ -238,6 +254,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param attr: 属性名
|
||||
:return: 属性值文本,没有该属性返回None
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.attr(attr)
|
||||
|
||||
def set_attr(self, attr, value):
|
||||
@ -246,6 +263,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param value: 属性值
|
||||
:return: None
|
||||
"""
|
||||
self._check_ok()
|
||||
self.frame_ele.set_attr(attr, value)
|
||||
|
||||
def remove_attr(self, attr):
|
||||
@ -253,6 +271,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param attr: 属性名
|
||||
:return: None
|
||||
"""
|
||||
self._check_ok()
|
||||
self.frame_ele.remove_attr(attr)
|
||||
|
||||
def run_script(self, script, as_expr=False, *args):
|
||||
@ -262,6 +281,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param args: 参数,按顺序在js文本中对应argument[0]、argument[1]...
|
||||
:return: 运行的结果
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.doc_ele.run_script(script, as_expr=as_expr, *args)
|
||||
|
||||
def parent(self, level_or_loc=1):
|
||||
@ -269,6 +289,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param level_or_loc: 第几级父元素,或定位符
|
||||
:return: 上级元素对象
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.parent(level_or_loc)
|
||||
|
||||
def prev(self, filter_loc='', index=1, timeout=0):
|
||||
@ -278,6 +299,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 兄弟元素
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.prev(filter_loc, index, timeout)
|
||||
|
||||
def next(self, filter_loc='', index=1, timeout=0):
|
||||
@ -287,6 +309,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 兄弟元素
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.next(filter_loc, index, timeout)
|
||||
|
||||
def before(self, filter_loc='', index=1, timeout=None):
|
||||
@ -296,6 +319,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 本元素前面的某个元素或节点
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.before(filter_loc, index, timeout)
|
||||
|
||||
def after(self, filter_loc='', index=1, timeout=None):
|
||||
@ -305,6 +329,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 本元素后面的某个元素或节点
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.after(filter_loc, index, timeout)
|
||||
|
||||
def prevs(self, filter_loc='', timeout=0):
|
||||
@ -313,6 +338,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 兄弟元素或节点文本组成的列表
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.prevs(filter_loc, timeout)
|
||||
|
||||
def nexts(self, filter_loc='', timeout=0):
|
||||
@ -321,6 +347,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 兄弟元素或节点文本组成的列表
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.nexts(filter_loc, timeout)
|
||||
|
||||
def befores(self, filter_loc='', timeout=None):
|
||||
@ -329,6 +356,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 查找元素的超时时间
|
||||
:return: 本元素前面的元素或节点组成的列表
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.frame_ele.befores(filter_loc, timeout)
|
||||
|
||||
def _ele(self, loc_or_ele, timeout=None, single=True, relative=False):
|
||||
@ -354,6 +382,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:param timeout: 连接超时时间
|
||||
:return: 是否成功,返回None表示不确定
|
||||
"""
|
||||
self._check_ok()
|
||||
err = None
|
||||
timeout = timeout if timeout is not None else self.timeouts.page_load
|
||||
|
||||
|
@ -30,6 +30,8 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
def _reload(self) -> None: ...
|
||||
|
||||
def _check_ok(self) -> None: ...
|
||||
|
||||
def _get_new_document(self) -> None: ...
|
||||
|
||||
def _onFrameAttached(self, **kwargs): ...
|
||||
|
@ -294,7 +294,7 @@ def _get_chrome_path(ini_path: str = None,
|
||||
|
||||
# -----------从系统变量中获取--------------
|
||||
if from_system_path:
|
||||
paths = popen('set path').read().lower()
|
||||
paths = popen('set path').read().encode('gbk').decode('utf-8').lower()
|
||||
r = search(r'[^;]*chrome[^;]*', paths)
|
||||
|
||||
if r:
|
||||
|
128
docs/WebPage使用方法/3.10动作链.md
Normal file
128
docs/WebPage使用方法/3.10动作链.md
Normal file
@ -0,0 +1,128 @@
|
||||
参考 selenium 的`ActionChains`,本库也提供了自己的`ActionChains`。语法更简洁易用,每个动作执行即生效,无须`perform()`。
|
||||
|
||||
# ✔ 创建对象
|
||||
|
||||
## 📍 `ActionChains`
|
||||
|
||||
创建动作链对象非常简单,只要把`WebPage`对象或`ChromiumPage`对象传入即可。动作链只在这个页面上生效。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `page`:`WebPage`对象或`ChromiumPage`对象
|
||||
|
||||
```python
|
||||
# 创建前先导入
|
||||
from DrissionPage import WebPage, ActionChains
|
||||
|
||||
page = WebPage()
|
||||
ac = ActionChains(page)
|
||||
```
|
||||
|
||||
# ✔ 移动鼠标
|
||||
|
||||
## 📍 `move_to()`
|
||||
|
||||
此方法用于移动鼠标到元素中点,或页面上的某个绝对坐标。可设置偏移量,当带偏移量时,偏移量相对于元素左上角坐标。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `ele_or_loc`:元素对象或绝对坐标,坐标为`tuple`(int, int) 形式
|
||||
|
||||
- `offset_x`:偏移量 x
|
||||
|
||||
- `offset_y`:偏移量 y
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
```python
|
||||
ele = page('tag:a')
|
||||
ac.move_to(ele_or_loc=ele) # 使鼠标移动过到 ele 元素上
|
||||
```
|
||||
|
||||
## 📍 `move()`
|
||||
|
||||
此方法用于使鼠标相对当前位置移动若干距离。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `offset_x`:偏移量 x
|
||||
|
||||
- `offset_y`:偏移量 y
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
```python
|
||||
ac.move(300, 0) # 鼠标向右移动 300 像素
|
||||
```
|
||||
|
||||
## 📍 `up()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向上移动若干距离。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `pixel`:移动距离
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
```python
|
||||
ac.up(50) # 鼠标向上移动 50 像素
|
||||
```
|
||||
|
||||
## 📍 `down()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向下移动若干距离。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `pixel`:移动距离
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
## 📍 `left()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向左移动若干距离。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `pixel`:移动距离
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
## 📍 `right()`
|
||||
|
||||
此方法用于使鼠标相对当前位置向右移动若干距离。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `pixel`:移动距离
|
||||
|
||||
**返回:**`ActionChains`对象自己
|
||||
|
||||
# ✔ 点击鼠标
|
||||
|
||||
## 📍 `click()`
|
||||
|
||||
## 📍 `r_click()`
|
||||
|
||||
## 📍 `hold()`
|
||||
|
||||
## 📍 `release()`
|
||||
|
||||
# ✔ 滚动滚轮
|
||||
|
||||
## 📍 `scroll()`
|
||||
|
||||
# ✔ 键盘按键
|
||||
|
||||
## 📍 `key_down()`
|
||||
|
||||
## 📍 `key_up()`
|
||||
|
||||
# ✔ 等待
|
||||
|
||||
## 📍 `wait()`
|
||||
|
||||
# ✔ 链式操作
|
||||
|
||||
|
@ -131,6 +131,15 @@ print(r.status_code)
|
||||
|
||||
此属性返回当前标签页的 id。
|
||||
|
||||
## 📍 `address`
|
||||
|
||||
此属性返回当前对象控制的页面地址和端口。
|
||||
|
||||
```python
|
||||
print(page.address)
|
||||
# 输出:127.0.0.1:9222
|
||||
```
|
||||
|
||||
## 📍 `driver`
|
||||
|
||||
此属性返回当前页面对象使用的`ChromiumDriver`对象。
|
||||
|
@ -22,6 +22,7 @@
|
||||
* [🔨 3.7 页面操作](WebPage使用方法\3.7页面操作.md)
|
||||
* [🔨 3.8 标签页操作](WebPage使用方法\3.8标签页操作.md)
|
||||
* [🔨 3.9 iframe操作](WebPage使用方法\3.9iframe操作.md)
|
||||
* [🔨 3.10 动作链](WebPage使用方法\3.10动作链.md)
|
||||
|
||||
* [🛠 4 MixPage 使用方法](#)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user