mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
解决新加载的iframe点击问题;对无位置和大小信息的元素进行处理
This commit is contained in:
parent
e8b22de2e3
commit
5dce3077ed
@ -15,7 +15,8 @@ from .chromium_driver import ChromiumDriver
|
||||
from .chromium_element import ChromiumWaiter, ChromiumScroll, ChromiumElement, run_js, make_chromium_ele, \
|
||||
ChromiumElementWaiter
|
||||
from .common.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
|
||||
from .common.errors import ContextLossError, ElementLossError, AlertExistsError, CallMethodError, TabClosedError
|
||||
from .common.errors import ContextLossError, ElementLossError, AlertExistsError, CallMethodError, TabClosedError, \
|
||||
NoRectError
|
||||
from .common.locator import get_loc
|
||||
from .common.tools import get_usable_path
|
||||
from .common.web import offset_scroll, cookies_to_tuple
|
||||
@ -346,6 +347,8 @@ class ChromiumBase(BasePage):
|
||||
raise TabClosedError
|
||||
elif r[ERROR] == 'alert exists':
|
||||
pass
|
||||
elif r[ERROR] in ('Node does not have a layout object', 'Could not compute box model.'):
|
||||
raise NoRectError
|
||||
elif r['type'] == 'call_method_error':
|
||||
raise CallMethodError(f'\n错误:{r["error"]}\nmethod:{r["method"]}\nargs:{r["args"]}')
|
||||
else:
|
||||
@ -924,7 +927,7 @@ class ChromiumPageScroll(ChromiumScroll):
|
||||
"""
|
||||
ele = self._driver.ele(loc_or_ele)
|
||||
try:
|
||||
self._driver.run_cdp('DOM.scrollIntoViewIfNeeded', nodeId=ele.node_id)
|
||||
self._driver.run_cdp('DOM.scrollIntoViewIfNeeded', nodeId=ele.ids.node_id)
|
||||
except Exception:
|
||||
ele.run_js("this.scrollIntoView();")
|
||||
|
||||
|
@ -11,7 +11,7 @@ from warnings import warn
|
||||
|
||||
from .base import DrissionElement, BaseElement
|
||||
from .common.constants import FRAME_ELEMENT, NoneElement
|
||||
from .common.errors import ContextLossError, ElementLossError, JavaScriptError
|
||||
from .common.errors import ContextLossError, ElementLossError, JavaScriptError, NoRectError
|
||||
from .common.locator import get_loc
|
||||
from .common.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll
|
||||
from .keys import _keys_to_typing, _keyDescriptionForString, _keyDefinitions
|
||||
@ -1515,37 +1515,37 @@ class Locations(object):
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
cl = self.viewport_location
|
||||
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def midpoint(self):
|
||||
"""返回元素中间点的绝对坐标"""
|
||||
cl = self.viewport_midpoint
|
||||
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def click_point(self):
|
||||
"""返回元素接受点击的点的绝对坐标"""
|
||||
cl = self.viewport_click_point
|
||||
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def viewport_location(self):
|
||||
"""返回元素左上角在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
return (int(m[0]), int(m[1])) if m else (0, 0)
|
||||
return int(m[0]), int(m[1])
|
||||
|
||||
@property
|
||||
def viewport_midpoint(self):
|
||||
"""返回元素中间点在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
return (int(m[0] + (m[2] - m[0]) // 2), int(m[3] + (m[5] - m[3]) // 2)) if m else (0, 0)
|
||||
return int(m[0] + (m[2] - m[0]) // 2), int(m[3] + (m[5] - m[3]) // 2)
|
||||
|
||||
@property
|
||||
def viewport_click_point(self):
|
||||
"""返回元素接受点击的点视口坐标"""
|
||||
m = self._get_viewport_rect('padding')
|
||||
return (int(self.viewport_midpoint[0]), int(m[1]) + 1) if m else (0, 0)
|
||||
return int(self.viewport_midpoint[0]), int(m[1]) + 1
|
||||
|
||||
@property
|
||||
def screen_location(self):
|
||||
@ -1573,10 +1573,7 @@ class Locations(object):
|
||||
:param quad: 方框类型,margin border padding
|
||||
:return: 四个角坐标,大小为0时返回None
|
||||
"""
|
||||
try:
|
||||
return self._ele.page.run_cdp('DOM.getBoxModel', nodeId=self._ele.ids.node_id)['model'][quad]
|
||||
except Exception:
|
||||
return None
|
||||
return self._ele.page.run_cdp('DOM.getBoxModel', nodeId=self._ele.ids.node_id)['model'][quad]
|
||||
|
||||
def _get_page_coord(self, x, y):
|
||||
"""根据绝对坐标获取窗口坐标"""
|
||||
@ -1628,25 +1625,29 @@ class Click(object):
|
||||
return True
|
||||
|
||||
if not by_js:
|
||||
self._ele.page.scroll.to_see(self._ele)
|
||||
if self._ele.states.is_in_viewport:
|
||||
client_x, client_y = self._ele.locations.viewport_click_point
|
||||
if client_x:
|
||||
loc_x, loc_y = self._ele.locations.click_point
|
||||
try:
|
||||
self._ele.page.scroll.to_see(self._ele)
|
||||
if self._ele.states.is_in_viewport:
|
||||
client_x, client_y = self._ele.locations.viewport_click_point
|
||||
if client_x:
|
||||
loc_x, loc_y = self._ele.locations.click_point
|
||||
|
||||
click = do_it(client_x, client_y, loc_x, loc_y)
|
||||
if click:
|
||||
self._ele.page.wait.load_start(wait_loading)
|
||||
return True
|
||||
|
||||
timeout = timeout if timeout is not None else self._ele.page.timeout
|
||||
end_time = perf_counter() + timeout
|
||||
while click is False and perf_counter() < end_time:
|
||||
click = do_it(client_x, client_y, loc_x, loc_y)
|
||||
if click:
|
||||
self._ele.page.wait.load_start(wait_loading)
|
||||
return True
|
||||
|
||||
if click is not None:
|
||||
self._ele.page.wait.load_start(wait_loading)
|
||||
return True
|
||||
timeout = timeout if timeout is not None else self._ele.page.timeout
|
||||
end_time = perf_counter() + timeout
|
||||
while click is False and perf_counter() < end_time:
|
||||
click = do_it(client_x, client_y, loc_x, loc_y)
|
||||
|
||||
if click is not None:
|
||||
self._ele.page.wait.load_start(wait_loading)
|
||||
return True
|
||||
|
||||
except NoRectError:
|
||||
by_js = True
|
||||
|
||||
if by_js is not False:
|
||||
self._ele.run_js('this.click();')
|
||||
|
@ -84,7 +84,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
self._reload()
|
||||
|
||||
try:
|
||||
self.run_cdp('DOM.describeNode', nodeId=self.ids.node_id)
|
||||
self.page.run_cdp('DOM.describeNode', nodeId=self.ids.node_id)
|
||||
except Exception:
|
||||
self._reload()
|
||||
# sleep(2)
|
||||
@ -291,7 +291,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
:return: 运行的结果
|
||||
"""
|
||||
self._check_ok()
|
||||
return self.doc_ele.run_js(script, as_expr=as_expr, *args)
|
||||
return self.doc_ele.run_js(script, *args, as_expr=as_expr)
|
||||
|
||||
def parent(self, level_or_loc=1):
|
||||
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
||||
@ -531,7 +531,7 @@ class ChromiumFrameScroll(ChromiumPageScroll):
|
||||
"""
|
||||
ele = loc_or_ele if isinstance(loc_or_ele, ChromiumElement) else self._driver.ele(loc_or_ele)
|
||||
try:
|
||||
self._driver.page.run_cdp('DOM.scrollIntoViewIfNeeded', nodeId=ele.node_id)
|
||||
self._driver.page.run_cdp('DOM.scrollIntoViewIfNeeded', nodeId=ele.ids.node_id)
|
||||
except Exception:
|
||||
ele.run_js("this.scrollIntoView();")
|
||||
|
||||
|
@ -38,3 +38,7 @@ class NotElementFoundError(BaseError):
|
||||
|
||||
class JavaScriptError(BaseError):
|
||||
_info = 'JavaScript运行错误。'
|
||||
|
||||
|
||||
class NoRectError(BaseError):
|
||||
_info = '该元素没有位置及大小。'
|
||||
|
Loading…
x
Reference in New Issue
Block a user