scroll.to_see()方法center参数默认None;解决滚动后点击被固定元素遮挡问题;get()支持ipv6地址;page对象增加user_agent属性

This commit is contained in:
g1879 2023-07-27 15:33:55 +08:00
parent d5da98084b
commit 8f33a9241e
13 changed files with 66 additions and 23 deletions

View File

@ -387,7 +387,7 @@ class BasePage(BaseParser):
:param interval: 重试间隔 :param interval: 重试间隔
:return: 重试次数和间隔组成的tuple :return: 重试次数和间隔组成的tuple
""" """
self._url = quote(url, safe='/:&?=%;#@+!') self._url = quote(url, safe='/:&?=%;#@+![]')
retry = retry if retry is not None else self.retry_times retry = retry if retry is not None else self.retry_times
interval = interval if interval is not None else self.retry_interval interval = interval if interval is not None else self.retry_interval
return retry, interval return retry, interval

View File

@ -325,6 +325,11 @@ class ChromiumBase(BasePage):
"""返回页面加载策略有3种'none''normal''eager'""" """返回页面加载策略有3种'none''normal''eager'"""
return self._page_load_strategy return self._page_load_strategy
@property
def user_agent(self):
"""返回user agent"""
return self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
@property @property
def scroll(self): def scroll(self):
"""返回用于滚动滚动条的对象""" """返回用于滚动滚动条的对象"""
@ -1174,10 +1179,10 @@ class ChromiumPageScroll(ChromiumScroll):
self.t1 = 'window' self.t1 = 'window'
self.t2 = 'document.documentElement' self.t2 = 'document.documentElement'
def to_see(self, loc_or_ele, center=False): def to_see(self, loc_or_ele, center=None):
"""滚动页面直到元素可见 """滚动页面直到元素可见
:param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串 :param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串
:param center: 是否尽量滚动到页面正中 :param center: 是否尽量滚动到页面正中为None时如果被遮挡则滚动到页面正中
:return: None :return: None
""" """
ele = self._driver._ele(loc_or_ele) ele = self._driver._ele(loc_or_ele)
@ -1186,17 +1191,22 @@ class ChromiumPageScroll(ChromiumScroll):
def _to_see(self, ele, center): def _to_see(self, ele, center):
"""执行滚动页面直到元素可见 """执行滚动页面直到元素可见
:param ele: 元素对象 :param ele: 元素对象
:param center: 是否尽量滚动到页面正中 :param center: 是否尽量滚动到页面正中为None时如果被遮挡则滚动到页面正中
:return: None :return: None
""" """
if center: txt = 'true' if center else 'false'
ele.run_js('this.scrollIntoViewIfNeeded();') ele.run_js(f'this.scrollIntoViewIfNeeded({txt});')
self._wait_scrolled() if center or (center is not False and ele.states.is_covered):
return ele.run_js('''function getWindowScrollTop() {var scroll_top = 0;
if (document.documentElement && document.documentElement.scrollTop) {
ele.run_js('this.scrollIntoViewIfNeeded(false);') scroll_top = document.documentElement.scrollTop;
if ele.states.is_covered: } else if (document.body) {scroll_top = document.body.scrollTop;}
ele.run_js('this.scrollIntoViewIfNeeded();') return scroll_top;}
const { top, height } = this.getBoundingClientRect();
const elCenter = top + height / 2;
const center = window.innerHeight / 2;
window.scrollTo({top: getWindowScrollTop() - (center - elCenter),
behavior: 'instant'});''')
self._wait_scrolled() self._wait_scrolled()

View File

@ -111,6 +111,9 @@ class ChromiumBase(BasePage):
@property @property
def page_load_strategy(self) -> str: ... def page_load_strategy(self) -> str: ...
@property
def user_agent(self) -> str: ...
@property @property
def scroll(self) -> ChromiumPageScroll: ... def scroll(self) -> ChromiumPageScroll: ...
@ -267,9 +270,9 @@ class NetworkListener(object):
class ChromiumPageScroll(ChromiumScroll): class ChromiumPageScroll(ChromiumScroll):
def __init__(self, page: ChromiumBase): ... def __init__(self, page: ChromiumBase): ...
def to_see(self, loc_or_ele: Union[str, tuple, ChromiumElement], center: bool = False) -> None: ... def to_see(self, loc_or_ele: Union[str, tuple, ChromiumElement], center: Union[bool, None] = None) -> None: ...
def _to_see(self, ele: ChromiumElement, center: bool) -> None: ... def _to_see(self, ele: ChromiumElement, center: Union[bool, None]) -> None: ...
class ChromiumBaseSetter(object): class ChromiumBaseSetter(object):

View File

@ -1771,9 +1771,9 @@ class ChromiumScroll(object):
class ChromiumElementScroll(ChromiumScroll): class ChromiumElementScroll(ChromiumScroll):
def to_see(self, center=False): def to_see(self, center=None):
"""滚动页面直到元素可见 """滚动页面直到元素可见
:param center: 是否尽量滚动到页面正中 :param center: 是否尽量滚动到页面正中为None时如果被遮挡则滚动到页面正中
:return: None :return: None
""" """
self._driver.page.scroll.to_see(self._driver, center=center) self._driver.page.scroll.to_see(self._driver, center=center)

View File

@ -496,7 +496,7 @@ class ChromiumScroll(object):
class ChromiumElementScroll(ChromiumScroll): class ChromiumElementScroll(ChromiumScroll):
def to_see(self, center: bool = False) -> None: ... def to_see(self, center: Union[bool, None] = None) -> None: ...
class ChromiumSelect(object): class ChromiumSelect(object):

View File

@ -638,10 +638,10 @@ class ChromiumFrameScroll(ChromiumPageScroll):
self.t1 = self.t2 = 'this.documentElement' self.t1 = self.t2 = 'this.documentElement'
self._wait_complete = False self._wait_complete = False
def to_see(self, loc_or_ele, center=False): def to_see(self, loc_or_ele, center=None):
"""滚动页面直到元素可见 """滚动页面直到元素可见
:param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串 :param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串
:param center: 是否尽量滚动到页面正中 :param center: 是否尽量滚动到页面正中为None时如果被遮挡则滚动到页面正中
:return: None :return: None
""" """
ele = loc_or_ele if isinstance(loc_or_ele, ChromiumElement) else self._driver._ele(loc_or_ele) ele = loc_or_ele if isinstance(loc_or_ele, ChromiumElement) else self._driver._ele(loc_or_ele)

View File

@ -203,7 +203,7 @@ class ChromiumFrameIds(object):
class ChromiumFrameScroll(ChromiumPageScroll): class ChromiumFrameScroll(ChromiumPageScroll):
def __init__(self, frame: ChromiumFrame) -> None: ... def __init__(self, frame: ChromiumFrame) -> None: ...
def to_see(self, loc_or_ele: Union[str, tuple, ChromiumElement], center: bool = False) -> None: ... def to_see(self, loc_or_ele: Union[str, tuple, ChromiumElement], center: Union[None, bool] = None) -> None: ...
class ChromiumFrameSetter(ChromiumBaseSetter): class ChromiumFrameSetter(ChromiumBaseSetter):

View File

@ -120,6 +120,14 @@ class WebPageTab(SessionPage, ChromiumTab):
"""以dict方式返回cookies""" """以dict方式返回cookies"""
return super().cookies return super().cookies
@property
def user_agent(self):
"""返回user agent"""
if self._mode == 's':
return super().user_agent
elif self._mode == 'd':
return super(SessionPage, self).user_agent
@property @property
def session(self): def session(self):
"""返回Session对象如未初始化则按配置信息创建""" """返回Session对象如未初始化则按配置信息创建"""

View File

@ -65,6 +65,9 @@ class WebPageTab(SessionPage, ChromiumTab):
@property @property
def cookies(self) -> dict: ... def cookies(self) -> dict: ...
@property
def user_agent(self) -> str: ...
@property @property
def session(self) -> Session: ... def session(self) -> Session: ...

View File

@ -98,6 +98,11 @@ class SessionPage(BasePage):
except Exception: except Exception:
return None return None
@property
def user_agent(self):
"""返回user agent"""
return self.session.headers.get('user-agent', '')
@property @property
def download_path(self): def download_path(self):
"""返回下载路径""" """返回下载路径"""

View File

@ -63,6 +63,9 @@ class SessionPage(BasePage):
@property @property
def json(self) -> Union[dict, None]: ... def json(self) -> Union[dict, None]: ...
@property
def user_agent(self) -> str: ...
@property @property
def download_path(self) -> str: ... def download_path(self) -> str: ...

View File

@ -187,6 +187,14 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""以dict方式返回cookies""" """以dict方式返回cookies"""
return super().cookies return super().cookies
@property
def user_agent(self):
"""返回user agent"""
if self._mode == 's':
return super().user_agent
elif self._mode == 'd':
return super(SessionPage, self).user_agent
@property @property
def session(self): def session(self):
"""返回Session对象如未初始化则按配置信息创建""" """返回Session对象如未初始化则按配置信息创建"""
@ -361,8 +369,8 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
return return
if copy_user_agent: if copy_user_agent:
selenium_user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self.session.headers.update({"User-Agent": selenium_user_agent}) self.session.headers.update({"User-Agent": user_agent})
set_session_cookies(self.session, super(SessionPage, self).get_cookies()) set_session_cookies(self.session, super(SessionPage, self).get_cookies())

View File

@ -67,6 +67,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
@property @property
def cookies(self) -> dict: ... def cookies(self) -> dict: ...
@property
def user_agent(self) -> str: ...
@property @property
def session(self) -> Session: ... def session(self) -> Session: ...