From 8456f7ad39056b3e37c411104d023ab99fe343e2 Mon Sep 17 00:00:00 2001 From: g1879 Date: Fri, 5 Jul 2024 11:27:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E4=BD=9C=E9=93=BE=E5=88=A0=E9=99=A4db?= =?UTF-8?q?=5Fclick()=EF=BC=9B=E5=90=84=E7=82=B9=E5=87=BB=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=A2=9E=E5=8A=A0times=E5=8F=82=E6=95=B0=EF=BC=9BTab?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=A2=9E=E5=8A=A0rect.scrollbar=5Fposition?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=9B=E4=BC=98=E5=8C=96=E7=82=B9=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/_base/driver.py | 2 +- DrissionPage/_elements/chromium_element.py | 6 ++--- DrissionPage/_functions/web.py | 10 +++----- DrissionPage/_units/actions.py | 23 +++++++---------- DrissionPage/_units/actions.pyi | 8 +++--- DrissionPage/_units/clicker.py | 30 ++++++++++++---------- DrissionPage/_units/rect.py | 6 +++++ DrissionPage/_units/rect.pyi | 3 +++ 8 files changed, 44 insertions(+), 44 deletions(-) diff --git a/DrissionPage/_base/driver.py b/DrissionPage/_base/driver.py index 0cd3471..22b2b31 100644 --- a/DrissionPage/_base/driver.py +++ b/DrissionPage/_base/driver.py @@ -192,7 +192,7 @@ class Driver(object): if 'result' not in result and 'error' in result: kwargs['_timeout'] = timeout return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'), - 'method': _method, 'args': kwargs, 'data': result['error']['data']} + 'method': _method, 'args': kwargs, 'data': result['error'].get('data')} else: return result['result'] diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 7326e75..091593f 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -19,7 +19,7 @@ from .._base.base import DrissionElement, BaseElement from .._functions.elements import ChromiumElementsList from .._functions.keys import input_text_or_keys from .._functions.locator import get_loc, locator_to_tuple -from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, offset_scroll, get_blob +from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, get_blob from .._units.clicker import Clicker from .._units.rect import ElementRect from .._units.scroller import ElementScroller @@ -787,9 +787,7 @@ class ChromiumElement(DrissionElement): :param offset_y: 相对元素左上角坐标的y轴偏移量 :return: None """ - self.owner.scroll.to_see(self) - x, y = offset_scroll(self, offset_x, offset_y) - self.owner._run_cdp('Input.dispatchMouseEvent', type='mouseMoved', x=x, y=y, _ignore=AlertExistsError) + self.owner.actions.move_to(self, offset_x=offset_x, offset_y=offset_y, duration=.1) def drag(self, offset_x=0, offset_y=0, duration=.5): """拖拽当前元素到相对位置 diff --git a/DrissionPage/_functions/web.py b/DrissionPage/_functions/web.py index 7c1854d..c9b1987 100644 --- a/DrissionPage/_functions/web.py +++ b/DrissionPage/_functions/web.py @@ -107,12 +107,12 @@ def location_in_viewport(page, loc_x, loc_y): def offset_scroll(ele, offset_x, offset_y): - """接收元素及偏移坐标,把坐标滚动到页面中间,返回该点在视口中的坐标 + """接收元素及偏移坐标,把坐标滚动到页面中间,返回该点绝对坐标 有偏移量时以元素左上角坐标为基准,没有时以click_point为基准 :param ele: 元素对象 :param offset_x: 偏移量x :param offset_y: 偏移量y - :return: 视口中的坐标 + :return: 绝对坐标 """ loc_x, loc_y = ele.rect.location cp_x, cp_y = ele.rect.click_point @@ -122,11 +122,7 @@ def offset_scroll(ele, offset_x, offset_y): clientWidth = ele.owner._run_js('return document.body.clientWidth;') clientHeight = ele.owner._run_js('return document.body.clientHeight;') ele.owner.scroll.to_location(lx - clientWidth // 2, ly - clientHeight // 2) - cl_x, cl_y = ele.rect.viewport_location - ccp_x, ccp_y = ele.rect.viewport_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 + return lx, ly def make_absolute_link(link, baseURI=None): diff --git a/DrissionPage/_units/actions.py b/DrissionPage/_units/actions.py index 72f90b8..e920529 100644 --- a/DrissionPage/_units/actions.py +++ b/DrissionPage/_units/actions.py @@ -94,36 +94,31 @@ class Actions: return self - def click(self, on_ele=None): + def click(self, on_ele=None, times=1): """点击鼠标左键,可先移动到元素上 :param on_ele: ChromiumElement元素或文本定位符 + :param times: 点击次数 :return: self """ - self._hold(on_ele, 'left').wait(.05)._release('left') + self._hold(on_ele, 'left', times).wait(.05)._release('left') return self - def r_click(self, on_ele=None): + def r_click(self, on_ele=None, times=1): """点击鼠标右键,可先移动到元素上 :param on_ele: ChromiumElement元素或文本定位符 + :param times: 点击次数 :return: self """ - self._hold(on_ele, 'right').wait(.05)._release('right') + self._hold(on_ele, 'right', times).wait(.05)._release('right') return self - def m_click(self, on_ele=None): + def m_click(self, on_ele=None, times=1): """点击鼠标中键,可先移动到元素上 :param on_ele: ChromiumElement元素或文本定位符 + :param times: 点击次数 :return: self """ - self._hold(on_ele, 'middle').wait(.05)._release('middle') - return self - - def db_click(self, on_ele=None): - """双击鼠标左键,可先移动到元素上 - :param on_ele: ChromiumElement元素或文本定位符 - :return: self - """ - self._hold(on_ele, 'left', 2).wait(.05)._release('left') + self._hold(on_ele, 'middle', times).wait(.05)._release('middle') return self def hold(self, on_ele=None): diff --git a/DrissionPage/_units/actions.pyi b/DrissionPage/_units/actions.pyi index ba07789..ad8f54a 100644 --- a/DrissionPage/_units/actions.pyi +++ b/DrissionPage/_units/actions.pyi @@ -57,13 +57,11 @@ class Actions: def move(self, offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions: ... - def click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ... + def click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ... - def r_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ... + def r_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ... - def m_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ... - - def db_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ... + def m_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ... def hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ... diff --git a/DrissionPage/_units/clicker.py b/DrissionPage/_units/clicker.py index 5f136bc..b748ad9 100644 --- a/DrissionPage/_units/clicker.py +++ b/DrissionPage/_units/clicker.py @@ -53,7 +53,7 @@ class Clicker(object): try: self._ele.scroll.to_see() if self._ele.states.is_enabled and self._ele.states.is_displayed: - rect = self._ele.rect.viewport_corners + rect = self._ele.rect.corners can_click = True except NoRectError: if by_js is False: @@ -90,12 +90,12 @@ class Clicker(object): r = self._ele.owner._run_cdp('DOM.getNodeForLocation', x=int(x), y=int(y), includeUserAgentShadowDOM=True, ignorePointerEventsNone=True) if r['backendNodeId'] != self._ele._backend_id: - vx, vy = self._ele.rect.viewport_midpoint + vx, vy = self._ele.rect.midpoint else: - vx, vy = self._ele.rect.viewport_click_point + vx, vy = self._ele.rect.click_point except CDPError: - vx, vy = self._ele.rect.viewport_midpoint + vx, vy = self._ele.rect.midpoint self._click(vx, vy) return True @@ -110,7 +110,7 @@ class Clicker(object): def right(self): """右键单击""" self._ele.owner.scroll.to_see(self._ele) - x, y = self._ele.rect.viewport_click_point + x, y = self._ele.rect.click_point self._click(x, y, 'right') def middle(self, get_tab=True): @@ -119,7 +119,7 @@ class Clicker(object): :return: Tab对象或None """ self._ele.owner.scroll.to_see(self._ele) - x, y = self._ele.rect.viewport_click_point + x, y = self._ele.rect.click_point curr_tid = self._ele.tab.browser.tab_ids[0] self._click(x, y, 'middle') if get_tab: @@ -198,15 +198,19 @@ class Clicker(object): return (self._ele.tab.browser.get_mix_tab(tid) if self._ele.tab._type == 'MixTab' else self._ele.tab.browser.get_tab(tid)) - def _click(self, client_x, client_y, button='left', count=1): + def _click(self, loc_x, loc_y, button='left', count=1): """实施点击 - :param client_x: 视口中的x坐标 - :param client_y: 视口中的y坐标 + :param loc_x: 绝对x坐标 + :param loc_y: 绝对y坐标 :param button: 'left' 'right' 'middle' 'back' 'forward' :param count: 点击次数 :return: None """ - self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=client_x, - y=client_y, button=button, clickCount=count, _ignore=AlertExistsError) - self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=client_x, - y=client_y, button=button, _ignore=AlertExistsError) + self._ele.owner.actions.move_to((loc_x, loc_y), duration=.1) + sx, sy = self._ele.owner.rect.scrollbar_position + x = loc_x - sx + y = loc_y - sy + self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=x, + y=y, button=button, clickCount=count, _ignore=AlertExistsError) + self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=x, + y=y, button=button, _ignore=AlertExistsError) diff --git a/DrissionPage/_units/rect.py b/DrissionPage/_units/rect.py index 68e8683..43bfaef 100644 --- a/DrissionPage/_units/rect.py +++ b/DrissionPage/_units/rect.py @@ -176,6 +176,12 @@ class TabRect(object): w, h = r.split(' ') return int(w), int(h) + @property + def scrollbar_position(self): + """返回滚动条位置,格式:(x, y)""" + r = self._get_page_rect()['visualViewport'] + return r['pageX'], r['pageY'] + def _get_page_rect(self): """获取页面范围信息""" return self._owner._run_cdp_loaded('Page.getLayoutMetrics') diff --git a/DrissionPage/_units/rect.pyi b/DrissionPage/_units/rect.pyi index c1df2d5..dff526d 100644 --- a/DrissionPage/_units/rect.pyi +++ b/DrissionPage/_units/rect.pyi @@ -89,6 +89,9 @@ class TabRect(object): @property def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ... + @property + def scrollbar_position(self) -> Tuple[int, int]: ... + def _get_page_rect(self) -> dict: ... def _get_window_rect(self) -> dict: ...