From 8f33a9241e036a019187f219f202f1d2e164cf8b Mon Sep 17 00:00:00 2001 From: g1879 Date: Thu, 27 Jul 2023 15:33:55 +0800 Subject: [PATCH] =?UTF-8?q?scroll.to=5Fsee()=E6=96=B9=E6=B3=95center?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=BB=98=E8=AE=A4None=EF=BC=9B=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=BB=9A=E5=8A=A8=E5=90=8E=E7=82=B9=E5=87=BB=E8=A2=AB?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E5=85=83=E7=B4=A0=E9=81=AE=E6=8C=A1=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9Bget()=E6=94=AF=E6=8C=81ipv6=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=EF=BC=9Bpage=E5=AF=B9=E8=B1=A1=E5=A2=9E=E5=8A=A0user=5Fagent?= =?UTF-8?q?=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/base.py | 2 +- DrissionPage/chromium_base.py | 32 ++++++++++++++++++++----------- DrissionPage/chromium_base.pyi | 9 ++++++--- DrissionPage/chromium_element.py | 4 ++-- DrissionPage/chromium_element.pyi | 2 +- DrissionPage/chromium_frame.py | 4 ++-- DrissionPage/chromium_frame.pyi | 2 +- DrissionPage/chromium_tab.py | 8 ++++++++ DrissionPage/chromium_tab.pyi | 3 +++ DrissionPage/session_page.py | 5 +++++ DrissionPage/session_page.pyi | 3 +++ DrissionPage/web_page.py | 12 ++++++++++-- DrissionPage/web_page.pyi | 3 +++ 13 files changed, 66 insertions(+), 23 deletions(-) diff --git a/DrissionPage/base.py b/DrissionPage/base.py index 58ff3f3..6800ca6 100644 --- a/DrissionPage/base.py +++ b/DrissionPage/base.py @@ -387,7 +387,7 @@ class BasePage(BaseParser): :param interval: 重试间隔 :return: 重试次数和间隔组成的tuple """ - self._url = quote(url, safe='/:&?=%;#@+!') + self._url = quote(url, safe='/:&?=%;#@+![]') retry = retry if retry is not None else self.retry_times interval = interval if interval is not None else self.retry_interval return retry, interval diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py index 5392087..a86d5a1 100644 --- a/DrissionPage/chromium_base.py +++ b/DrissionPage/chromium_base.py @@ -325,6 +325,11 @@ class ChromiumBase(BasePage): """返回页面加载策略,有3种:'none'、'normal'、'eager'""" return self._page_load_strategy + @property + def user_agent(self): + """返回user agent""" + return self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] + @property def scroll(self): """返回用于滚动滚动条的对象""" @@ -1174,10 +1179,10 @@ class ChromiumPageScroll(ChromiumScroll): self.t1 = 'window' 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 center: 是否尽量滚动到页面正中 + :param center: 是否尽量滚动到页面正中,为None时如果被遮挡,则滚动到页面正中 :return: None """ ele = self._driver._ele(loc_or_ele) @@ -1186,17 +1191,22 @@ class ChromiumPageScroll(ChromiumScroll): def _to_see(self, ele, center): """执行滚动页面直到元素可见 :param ele: 元素对象 - :param center: 是否尽量滚动到页面正中 + :param center: 是否尽量滚动到页面正中,为None时如果被遮挡,则滚动到页面正中 :return: None """ - if center: - ele.run_js('this.scrollIntoViewIfNeeded();') - self._wait_scrolled() - return - - ele.run_js('this.scrollIntoViewIfNeeded(false);') - if ele.states.is_covered: - ele.run_js('this.scrollIntoViewIfNeeded();') + txt = 'true' if center else 'false' + ele.run_js(f'this.scrollIntoViewIfNeeded({txt});') + if center or (center is not False and ele.states.is_covered): + ele.run_js('''function getWindowScrollTop() {var scroll_top = 0; + if (document.documentElement && document.documentElement.scrollTop) { + scroll_top = document.documentElement.scrollTop; + } else if (document.body) {scroll_top = document.body.scrollTop;} + 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() diff --git a/DrissionPage/chromium_base.pyi b/DrissionPage/chromium_base.pyi index 9638dc8..94d962d 100644 --- a/DrissionPage/chromium_base.pyi +++ b/DrissionPage/chromium_base.pyi @@ -111,6 +111,9 @@ class ChromiumBase(BasePage): @property def page_load_strategy(self) -> str: ... + @property + def user_agent(self) -> str: ... + @property def scroll(self) -> ChromiumPageScroll: ... @@ -267,9 +270,9 @@ class NetworkListener(object): class ChromiumPageScroll(ChromiumScroll): 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): @@ -366,4 +369,4 @@ class ScreencastMode(object): def frugal_imgs_mode(self) -> None: ... - def imgs_mode(self) -> None: ... \ No newline at end of file + def imgs_mode(self) -> None: ... diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index 59f4eb0..e76ad7a 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -1771,9 +1771,9 @@ class ChromiumScroll(object): class ChromiumElementScroll(ChromiumScroll): - def to_see(self, center=False): + def to_see(self, center=None): """滚动页面直到元素可见 - :param center: 是否尽量滚动到页面正中 + :param center: 是否尽量滚动到页面正中,为None时如果被遮挡,则滚动到页面正中 :return: None """ self._driver.page.scroll.to_see(self._driver, center=center) diff --git a/DrissionPage/chromium_element.pyi b/DrissionPage/chromium_element.pyi index 53538ff..1084c65 100644 --- a/DrissionPage/chromium_element.pyi +++ b/DrissionPage/chromium_element.pyi @@ -496,7 +496,7 @@ class ChromiumScroll(object): class ChromiumElementScroll(ChromiumScroll): - def to_see(self, center: bool = False) -> None: ... + def to_see(self, center: Union[bool, None] = None) -> None: ... class ChromiumSelect(object): diff --git a/DrissionPage/chromium_frame.py b/DrissionPage/chromium_frame.py index f9118c4..374df89 100644 --- a/DrissionPage/chromium_frame.py +++ b/DrissionPage/chromium_frame.py @@ -638,10 +638,10 @@ class ChromiumFrameScroll(ChromiumPageScroll): self.t1 = self.t2 = 'this.documentElement' 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 center: 是否尽量滚动到页面正中 + :param center: 是否尽量滚动到页面正中,为None时如果被遮挡,则滚动到页面正中 :return: None """ ele = loc_or_ele if isinstance(loc_or_ele, ChromiumElement) else self._driver._ele(loc_or_ele) diff --git a/DrissionPage/chromium_frame.pyi b/DrissionPage/chromium_frame.pyi index 631fb5f..5326e53 100644 --- a/DrissionPage/chromium_frame.pyi +++ b/DrissionPage/chromium_frame.pyi @@ -203,7 +203,7 @@ class ChromiumFrameIds(object): class ChromiumFrameScroll(ChromiumPageScroll): 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): diff --git a/DrissionPage/chromium_tab.py b/DrissionPage/chromium_tab.py index 50ad5c7..46716b8 100644 --- a/DrissionPage/chromium_tab.py +++ b/DrissionPage/chromium_tab.py @@ -120,6 +120,14 @@ class WebPageTab(SessionPage, ChromiumTab): """以dict方式返回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 def session(self): """返回Session对象,如未初始化则按配置信息创建""" diff --git a/DrissionPage/chromium_tab.pyi b/DrissionPage/chromium_tab.pyi index b2d0428..fc1b132 100644 --- a/DrissionPage/chromium_tab.pyi +++ b/DrissionPage/chromium_tab.pyi @@ -65,6 +65,9 @@ class WebPageTab(SessionPage, ChromiumTab): @property def cookies(self) -> dict: ... + @property + def user_agent(self) -> str: ... + @property def session(self) -> Session: ... diff --git a/DrissionPage/session_page.py b/DrissionPage/session_page.py index 3d934b9..08a12bf 100644 --- a/DrissionPage/session_page.py +++ b/DrissionPage/session_page.py @@ -98,6 +98,11 @@ class SessionPage(BasePage): except Exception: return None + @property + def user_agent(self): + """返回user agent""" + return self.session.headers.get('user-agent', '') + @property def download_path(self): """返回下载路径""" diff --git a/DrissionPage/session_page.pyi b/DrissionPage/session_page.pyi index c551834..3a32942 100644 --- a/DrissionPage/session_page.pyi +++ b/DrissionPage/session_page.pyi @@ -63,6 +63,9 @@ class SessionPage(BasePage): @property def json(self) -> Union[dict, None]: ... + @property + def user_agent(self) -> str: ... + @property def download_path(self) -> str: ... diff --git a/DrissionPage/web_page.py b/DrissionPage/web_page.py index 8c3dd5e..71dc778 100644 --- a/DrissionPage/web_page.py +++ b/DrissionPage/web_page.py @@ -187,6 +187,14 @@ class WebPage(SessionPage, ChromiumPage, BasePage): """以dict方式返回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 def session(self): """返回Session对象,如未初始化则按配置信息创建""" @@ -361,8 +369,8 @@ class WebPage(SessionPage, ChromiumPage, BasePage): return if copy_user_agent: - selenium_user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] - self.session.headers.update({"User-Agent": selenium_user_agent}) + user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] + self.session.headers.update({"User-Agent": user_agent}) set_session_cookies(self.session, super(SessionPage, self).get_cookies()) diff --git a/DrissionPage/web_page.pyi b/DrissionPage/web_page.pyi index 475468a..d9ddda2 100644 --- a/DrissionPage/web_page.pyi +++ b/DrissionPage/web_page.pyi @@ -67,6 +67,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage): @property def cookies(self) -> dict: ... + @property + def user_agent(self) -> str: ... + @property def session(self) -> Session: ...