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: ...