完善页面查找元素逻辑;增加wait_loading方法和参数

This commit is contained in:
g1879 2022-12-23 23:06:39 +08:00
parent 0ec2fb2bcb
commit 2bb8ca9dfb
3 changed files with 54 additions and 32 deletions

View File

@ -402,22 +402,31 @@ class ChromiumBase(BasePage):
search_result = self._wait_driver.DOM.performSearch(query=loc, includeUserAgentShadowDOM=True)
count = search_result['resultCount']
nodeIds = None
end_time = perf_counter() + timeout
while count == 0 and perf_counter() < end_time:
while True:
if count > 0:
count = 1 if single else count
try:
nodeIds = self._wait_driver.DOM.getSearchResults(searchId=search_result['searchId'],
fromIndex=0, toIndex=count)
break
except Exception:
sleep(.01)
if perf_counter() >= end_time:
break
search_result = self._wait_driver.DOM.performSearch(query=loc, includeUserAgentShadowDOM=True)
count = search_result['resultCount']
if count == 0:
if not nodeIds:
return None if single else []
count = 1 if single else count
nodeIds = self._wait_driver.DOM.getSearchResults(searchId=search_result['searchId'], fromIndex=0,
toIndex=count)
eles = []
for i in nodeIds['nodeIds']:
eles.append(make_chromium_ele(self, node_id=i))
return eles[0] if single else eles
if single:
return make_chromium_ele(self, node_id=nodeIds['nodeIds'][0])
else:
return [make_chromium_ele(self, node_id=i) for i in nodeIds['nodeIds']]
def wait_ele(self, loc_or_ele, timeout=None):
"""返回用于等待元素到达某个状态的等待器对象 \n

View File

@ -592,12 +592,13 @@ class ChromiumElement(DrissionElement):
else:
self.input(('\ue009', 'a', '\ue017'), clear=False)
def click(self, by_js=None, retry=False, timeout=.2):
def click(self, by_js=None, retry=False, timeout=.2, wait_loading=False):
"""点击元素 \n
如果遇到遮挡会重新尝试点击直到超时若都失败就改用js点击 \n
:param by_js: 是否用js点击为True时直接用js点击为False时重试失败也不会改用js
:param retry: 遇到其它元素遮挡时是否重试
:param timeout: 尝试点击的超时时间不指定则使用父页面的超时时间retry为True时才生效
:param wait_loading: 是否等待页面进入加载状态
:return: 是否点击成功
"""
@ -623,6 +624,8 @@ class ChromiumElement(DrissionElement):
click = do_it(client_x, client_y, loc_x, loc_y)
if click:
if wait_loading:
self.wait_loading()
return True
timeout = timeout if timeout is not None else self.page.timeout
@ -631,10 +634,14 @@ class ChromiumElement(DrissionElement):
click = do_it(client_x, client_y, loc_x, loc_y)
if click is not None:
if wait_loading:
self.wait_loading()
return True
if by_js is not False:
self.run_script('this.click();')
if wait_loading:
self.wait_loading()
return True
return False
@ -735,6 +742,18 @@ class ChromiumElement(DrissionElement):
current_x, current_y = x, y
actions.release()
def wait_loading(self, timeout=2):
"""阻塞程序,等待页面进入加载状态 \n
:param timeout: 超时时间
:return: 等待结束时是否进入加载状态
"""
end_time = perf_counter() + timeout
while perf_counter() < end_time:
if self.page.is_loading:
return True
sleep(.05)
return False
def _get_obj_id(self, node_id=None, backend_id=None):
"""根据传入node id获取js中的object id \n
:param node_id: cdp中的node id
@ -1146,19 +1165,15 @@ def _find_by_xpath(ele, xpath, single, timeout, relative=True):
userGesture=True)
if single:
if r['result']['subtype'] == 'null':
return None
else:
return make_chromium_ele(ele.page, obj_id=r['result']['objectId'])
return None if r['result']['subtype'] == 'null' else make_chromium_ele(ele.page, obj_id=r['result']['objectId'])
if r['result']['description'] == 'NodeList(0)':
return []
else:
if r['result']['description'] == 'NodeList(0)':
return []
else:
r = ele.page.driver.Runtime.getProperties(objectId=r['result']['objectId'], ownProperties=True)['result']
return [make_chromium_ele(ele.page, obj_id=i['value']['objectId'])
if i['value']['type'] == 'object' else i['value']['value']
for i in r[:-1]]
r = ele.page.driver.Runtime.getProperties(objectId=r['result']['objectId'], ownProperties=True)['result']
return [make_chromium_ele(ele.page, obj_id=i['value']['objectId'])
if i['value']['type'] == 'object' else i['value']['value']
for i in r[:-1]]
def _find_by_css(ele, selector, single, timeout):
@ -1187,17 +1202,13 @@ def _find_by_css(ele, selector, single, timeout):
userGesture=True)
if single:
if r['result']['subtype'] == 'null':
return None
else:
return make_chromium_ele(ele.page, obj_id=r['result']['objectId'])
return None if r['result']['subtype'] == 'null' else make_chromium_ele(ele.page, obj_id=r['result']['objectId'])
if r['result']['description'] == 'NodeList(0)':
return []
else:
if r['result']['description'] == 'NodeList(0)':
return []
else:
r = ele.page.driver.Runtime.getProperties(objectId=r['result']['objectId'], ownProperties=True)['result']
return [make_chromium_ele(ele.page, obj_id=i['value']['objectId']) for i in r]
r = ele.page.driver.Runtime.getProperties(objectId=r['result']['objectId'], ownProperties=True)['result']
return [make_chromium_ele(ele.page, obj_id=i['value']['objectId']) for i in r]
def make_chromium_ele(page, node_id=None, obj_id=None):

View File

@ -205,7 +205,7 @@ class ChromiumElement(DrissionElement):
def clear(self, by_js: bool = ...) -> None: ...
def click(self, by_js: bool = ..., retry: bool = ..., timeout: float = ...) -> bool: ...
def click(self, by_js: bool = ..., retry: bool = ..., timeout: float = ..., wait_loading: bool = ...) -> bool: ...
def click_at(self, offset_x: Union[int, str] = ..., offset_y: Union[int, str] = ..., button: str = ...) -> None: ...
@ -224,6 +224,8 @@ class ChromiumElement(DrissionElement):
speed: int = ...,
shake: bool = ...) -> None: ...
def wait_loading(self, timeout: float = ...) -> bool: ...
def _get_obj_id(self, node_id: str = ..., backend_id: str = ...) -> str: ...
def _get_node_id(self, obj_id: str = ..., backend_id: str = ...) -> str: ...