From 6255a096ba1b6e98752673ec5819bf0635b56f41 Mon Sep 17 00:00:00 2001 From: g1879 Date: Wed, 24 Jul 2024 11:53:11 +0800 Subject: [PATCH] =?UTF-8?q?ele.click()=E5=8F=96=E6=B6=88=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E8=BD=A8=E8=BF=B9=EF=BC=9Bwait.new=5Ftab()=E7=9A=84curr=5Ftab?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=8F=AF=E6=8E=A5=E6=94=B6Tab=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=EF=BC=9B=E4=BC=98=E5=8C=96=E7=AD=89=E5=BE=85=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=BE=E7=BD=AE=E5=90=8C=E6=97=B6ua?= =?UTF-8?q?=E5=92=8C=E6=97=A0=E5=A4=B4=E6=97=B6=E5=87=BA=E7=8E=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/_base/browser.py | 2 +- DrissionPage/_configs/chromium_options.py | 1 + DrissionPage/_configs/chromium_options.pyi | 1 + DrissionPage/_functions/browser.py | 2 ++ DrissionPage/_functions/elements.py | 2 +- DrissionPage/_functions/web.py | 4 ++-- DrissionPage/_functions/web.pyi | 2 +- DrissionPage/_units/clicker.py | 14 ++++---------- DrissionPage/_units/clicker.pyi | 3 +-- DrissionPage/_units/waiter.py | 17 +++++++++++------ DrissionPage/_units/waiter.pyi | 5 ++++- 11 files changed, 29 insertions(+), 24 deletions(-) diff --git a/DrissionPage/_base/browser.py b/DrissionPage/_base/browser.py index b01aec3..a22810e 100644 --- a/DrissionPage/_base/browser.py +++ b/DrissionPage/_base/browser.py @@ -81,7 +81,7 @@ class Chromium(object): self.address = self._chromium_options.address self._driver = BrowserDriver(self.id, 'browser', self.address, self) - if self.is_headless != self._chromium_options.is_headless or ( + if (not self._chromium_options._ua_set and self.is_headless != self._chromium_options.is_headless) or ( self._is_exists and self._chromium_options._new_env): self.quit(3, True) connect_browser(self._chromium_options) diff --git a/DrissionPage/_configs/chromium_options.py b/DrissionPage/_configs/chromium_options.py index bec890e..35e14c2 100644 --- a/DrissionPage/_configs/chromium_options.py +++ b/DrissionPage/_configs/chromium_options.py @@ -22,6 +22,7 @@ class ChromiumOptions(object): self._prefs_to_del = [] self.clear_file_flags = False self._is_headless = False + self._ua_set = False if read_file is False: ini_path = False diff --git a/DrissionPage/_configs/chromium_options.pyi b/DrissionPage/_configs/chromium_options.pyi index 10ba9a8..06875a1 100644 --- a/DrissionPage/_configs/chromium_options.pyi +++ b/DrissionPage/_configs/chromium_options.pyi @@ -34,6 +34,7 @@ class ChromiumOptions(object): _retry_times: int = ... _retry_interval: float = ... _is_headless: bool = ... + _ua_set: bool = ... def __init__(self, read_file: [bool, None] = True, ini_path: Union[str, Path] = None): ... diff --git a/DrissionPage/_functions/browser.py b/DrissionPage/_functions/browser.py index 9acae5d..9958bf0 100644 --- a/DrissionPage/_functions/browser.py +++ b/DrissionPage/_functions/browser.py @@ -81,6 +81,8 @@ def get_launch_args(opt): user_path = f'--user-data-dir={Path(i[16:]).absolute()}' result.add(user_path) continue + elif i.startswith('--user-agent='): + opt._ua_set = True result.add(i) if not user_path and not opt.system_user_path: diff --git a/DrissionPage/_functions/elements.py b/DrissionPage/_functions/elements.py index cccb8da..c91abfe 100644 --- a/DrissionPage/_functions/elements.py +++ b/DrissionPage/_functions/elements.py @@ -393,7 +393,7 @@ def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10): for loc in locators: if res[loc] is not False: continue - ele = owner.ele(loc, timeout=0) if first_ele else owner.eles(loc, timeout=0) + ele = owner._ele(loc, timeout=0, raise_err=False, index=1 if first_ele else None) if ele: res[loc] = ele if any_one: diff --git a/DrissionPage/_functions/web.py b/DrissionPage/_functions/web.py index f86605e..ccbc84c 100644 --- a/DrissionPage/_functions/web.py +++ b/DrissionPage/_functions/web.py @@ -136,7 +136,7 @@ def offset_scroll(ele, offset_x, offset_y): :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 @@ -150,7 +150,7 @@ def offset_scroll(ele, offset_x, offset_y): 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 lx, ly, cx, cy + return cx, cy def make_absolute_link(link, baseURI=None): diff --git a/DrissionPage/_functions/web.pyi b/DrissionPage/_functions/web.pyi index c7a40db..d09dfac 100644 --- a/DrissionPage/_functions/web.pyi +++ b/DrissionPage/_functions/web.pyi @@ -24,7 +24,7 @@ def format_html(text: str) -> str: ... def location_in_viewport(page: ChromiumBase, loc_x: float, loc_y: float) -> bool: ... -def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> Tuple[int, int, int, int]: ... +def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> Tuple[int, int]: ... def make_absolute_link(link: str, baseURI: str = None) -> str: ... diff --git a/DrissionPage/_units/clicker.py b/DrissionPage/_units/clicker.py index cb889ee..e020278 100644 --- a/DrissionPage/_units/clicker.py +++ b/DrissionPage/_units/clicker.py @@ -91,16 +91,13 @@ class Clicker(object): includeUserAgentShadowDOM=True, ignorePointerEventsNone=True) if r['backendNodeId'] != self._ele._backend_id: vx, vy = self._ele.rect.viewport_midpoint - lx, ly = self._ele.rect._get_page_coord(vx, vy) else: vx, vy = self._ele.rect.viewport_click_point - lx, ly = self._ele.rect._get_page_coord(vx, vy) except CDPError: vx, vy = self._ele.rect.viewport_midpoint - lx, ly = self._ele.rect._get_page_coord(vx, vy) - self._click(lx, ly, vx, vy) + self._click(vx, vy) return self._ele if by_js is not False: @@ -113,7 +110,7 @@ class Clicker(object): def right(self): """右键单击""" self._ele.owner.scroll.to_see(self._ele) - return self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='right') + return self._click(*self._ele.rect.viewport_click_point, button='right') def middle(self, get_tab=True): """中键单击,默认返回新出现的tab对象 @@ -122,7 +119,7 @@ class Clicker(object): """ self._ele.owner.scroll.to_see(self._ele) curr_tid = self._ele.tab.browser.tab_ids[0] - self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='middle') + self._click(*self._ele.rect.viewport_click_point, button='middle') if get_tab: tid = self._ele.tab.browser.wait.new_tab(curr_tab=curr_tid) if not tid: @@ -226,17 +223,14 @@ class Clicker(object): self.left(by_js=by_js) return True if self._ele.tab.wait.title_change(text=text, exclude=exclude, timeout=timeout) else False - def _click(self, loc_x, loc_y, view_x, view_y, button='left', count=1): + def _click(self, view_x, view_y, button='left', count=1): """实施点击 - :param loc_x: 绝对x坐标 - :param loc_y: 绝对y坐标 :param view_x: 视口x坐标 :param view_y: 视口y坐标 :param button: 'left' 'right' 'middle' 'back' 'forward' :param count: 点击次数 :return: None """ - self._ele.owner.actions.move_to((loc_x, loc_y), duration=.05) self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=view_x, y=view_y, button=button, clickCount=count, _ignore=AlertExistsError) self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=view_x, diff --git a/DrissionPage/_units/clicker.pyi b/DrissionPage/_units/clicker.pyi index 1511100..325b2ac 100644 --- a/DrissionPage/_units/clicker.pyi +++ b/DrissionPage/_units/clicker.pyi @@ -53,8 +53,7 @@ class Clicker(object): def for_title_change(self, text: str = None, exclude: bool = False, by_js: bool = False, timeout: float = None) -> bool: ... - def _click(self, loc_x: float, - loc_y: float, + def _click(self, view_x: float, view_y: float, button: str = 'left', diff --git a/DrissionPage/_units/waiter.py b/DrissionPage/_units/waiter.py index d988c01..101dd01 100644 --- a/DrissionPage/_units/waiter.py +++ b/DrissionPage/_units/waiter.py @@ -35,16 +35,19 @@ class BrowserWaiter(OriginWaiter): def new_tab(self, timeout=None, curr_tab=None, raise_err=None): """等待新标签页出现 :param timeout: 超时时间(秒),为None则使用页面对象timeout属性 - :param curr_tab: 指定当前最新的tab id,用于判断新tab出现,为None自动获取 + :param curr_tab: 指定当前最新的tab对象或tab id,用于判断新tab出现,为None自动获取 :param raise_err: 等待失败时是否报错,为None时根据Settings设置 :return: 等到新标签页返回其id,否则返回False """ - curr_tid = curr_tab if curr_tab else self._owner.tab_ids[0] + if not curr_tab: + curr_tab = self._owner.tab_ids[0] + elif hasattr(curr_tab, '_type'): + curr_tab = curr_tab.tab_id timeout = timeout if timeout is not None else self._owner.timeout end_time = perf_counter() + timeout while perf_counter() < end_time: latest_tid = self._owner.tab_ids[0] - if curr_tid != latest_tid: + if curr_tab != latest_tid: return latest_tid sleep(.01) @@ -193,7 +196,7 @@ class BaseWaiter(OriginWaiter): by = ('id', 'xpath', 'link text', 'partial link text', 'name', 'tag name', 'class name', 'css selector') locators = ((get_loc(locators)[1],) if (isinstance(locators, str) or isinstance(locators, tuple) and locators[0] in by and len(locators) == 2) - else [get_loc(l)[1] for l in locators]) + else [get_loc(x)[1] for x in locators]) method = any if any_one else all timeout = self._owner.timeout if timeout is None else timeout @@ -321,7 +324,8 @@ class BaseWaiter(OriginWaiter): :param raise_err: 等待失败时是否报错,为None时根据Settings设置 :return: 是否等待成功 """ - timeout = timeout if timeout is not None else self._owner.timeout + if timeout is None: + timeout = self._owner.timeout timeout = .1 if timeout <= 0 else timeout end_time = perf_counter() + timeout while perf_counter() < end_time: @@ -527,7 +531,8 @@ class ElementWaiter(OriginWaiter): :param raise_err: 等待失败时是否报错,为None时根据Settings设置 :return: 成功返回元素对象,失败返回False """ - timeout = timeout if timeout is not None else self._timeout + if timeout is None: + timeout = self._timeout t1 = perf_counter() r = self._wait_state('is_clickable', True, timeout, raise_err, err_text='等待元素可点击失败(等{}秒)。') r = self.stop_moving(timeout=timeout - perf_counter() + t1) if wait_moved and r else r diff --git a/DrissionPage/_units/waiter.pyi b/DrissionPage/_units/waiter.pyi index 9e3a70f..2e36810 100644 --- a/DrissionPage/_units/waiter.pyi +++ b/DrissionPage/_units/waiter.pyi @@ -34,7 +34,10 @@ class BrowserWaiter(OriginWaiter): def download_begin(self, timeout: float = None, cancel_it: bool = False) -> DownloadMission: ... - def new_tab(self, timeout: float = None, curr_tab: str = None, raise_err: bool = None) -> Union[str, bool]: ... + def new_tab(self, + timeout: float = None, + curr_tab: Union[str, ChromiumTab] = None, + raise_err: bool = None) -> Union[str, bool]: ... def all_downloads_done(self, timeout: float = None, cancel_if_timeout: bool = True) -> bool: ...