diff --git a/DrissionPage/_commons/browser.py b/DrissionPage/_commons/browser.py index dfd0ce1..c0a5e80 100644 --- a/DrissionPage/_commons/browser.py +++ b/DrissionPage/_commons/browser.py @@ -3,7 +3,7 @@ @Author : g1879 @Contact : g1879@qq.com """ -from json import load, dump +from json import load, dump, JSONDecodeError from pathlib import Path from subprocess import Popen, DEVNULL from tempfile import gettempdir @@ -105,7 +105,7 @@ def get_launch_args(opt): opt._headless = headless # ----------处理插件extensions------------- - ext = opt.extensions + ext = [str(Path(e).absolute()) for e in opt.extensions] if ext: ext = ','.join(set(ext)) ext = f'--load-extension={ext}' @@ -140,7 +140,10 @@ def set_prefs(opt): f.write('{}') with open(prefs_file, "r", encoding='utf-8') as f: - prefs_dict = load(f) + try: + prefs_dict = load(f) + except JSONDecodeError: + prefs_dict = {} for pref in prefs: value = prefs[pref] diff --git a/DrissionPage/_commons/web.pyi b/DrissionPage/_commons/web.pyi index eae78ce..d6b9dc2 100644 --- a/DrissionPage/_commons/web.pyi +++ b/DrissionPage/_commons/web.pyi @@ -9,9 +9,9 @@ from typing import Union from requests import Session from requests.cookies import RequestsCookieJar +from .._base.base import BasePage, DrissionElement from .._elements.chromium_element import ChromiumElement from .._pages.chromium_base import ChromiumBase -from ..base import DrissionElement, BasePage def get_ele_txt(e: DrissionElement) -> str: ... @@ -20,10 +20,10 @@ def get_ele_txt(e: DrissionElement) -> str: ... def format_html(text: str) -> str: ... -def location_in_viewport(page: ChromiumBase, loc_x: int, loc_y: int) -> bool: ... +def location_in_viewport(page: ChromiumBase, loc_x: float, loc_y: float) -> bool: ... -def offset_scroll(ele: ChromiumElement, offset_x: int, offset_y: int) -> tuple: ... +def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> tuple: ... def make_absolute_link(link, page: BasePage = None) -> str: ... diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index dcc0a4d..a6549bf 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -16,7 +16,7 @@ from .._commons.tools import get_usable_path from .._commons.web import make_absolute_link, get_ele_txt, format_html, is_js_func, offset_scroll from .._units.clicker import Clicker from .._units.element_states import ElementStates, ShadowRootStates -from .._units.ids import Ids, ElementIds +from .._units.ids import ShadowRootIds, ElementIds from .._units.locations import Locations from .._units.scroller import ElementScroller from .._units.select_element import SelectElement @@ -130,7 +130,7 @@ class ChromiumElement(DrissionElement): def size(self): """返回元素宽和高组成的元组""" border = self.page.run_cdp('DOM.getBoxModel', backendNodeId=self._backend_id)['model']['border'] - return int(border[2] - border[0]), int(border[5] - border[1]) + return border[2] - border[0], border[5] - border[1] @property def set(self): @@ -772,7 +772,7 @@ class ChromiumShadowRoot(BaseElement): self._obj_id = obj_id self._node_id = self._get_node_id(obj_id) self._backend_id = self._get_backend_id(self._node_id) - self._ids = Ids(self) + self._ids = ShadowRootIds(self) self._states = None def __repr__(self): diff --git a/DrissionPage/_elements/chromium_element.pyi b/DrissionPage/_elements/chromium_element.pyi index cf64a41..1108d9d 100644 --- a/DrissionPage/_elements/chromium_element.pyi +++ b/DrissionPage/_elements/chromium_element.pyi @@ -15,7 +15,7 @@ from .._pages.chromium_page import ChromiumPage from .._pages.web_page import WebPage from .._units.clicker import Clicker from .._units.element_states import ShadowRootStates, ElementStates -from .._units.ids import Ids, ElementIds +from .._units.ids import ElementIds, ShadowRootIds from .._units.locations import Locations from .._units.scroller import ElementScroller from .._units.select_element import SelectElement @@ -25,9 +25,7 @@ from .._units.waiter import ElementWaiter class ChromiumElement(DrissionElement): - def __init__(self, - page: ChromiumBase, - node_id: str = None, obj_id: str = None, backend_id: str = None): + def __init__(self, page: ChromiumBase, node_id: str = None, obj_id: str = None, backend_id: str = None): self._tag: str = ... self.page: Union[ChromiumPage, WebPage] = ... self._node_id: str = ... @@ -46,8 +44,7 @@ class ChromiumElement(DrissionElement): def __repr__(self) -> str: ... - def __call__(self, - loc_or_str: Union[Tuple[str, str], str], + def __call__(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> Union[ChromiumElement, str, None]: ... @property @@ -73,7 +70,7 @@ class ChromiumElement(DrissionElement): def ids(self) -> ElementIds: ... @property - def size(self) -> Tuple[int, int]: ... + def size(self) -> Tuple[float, float]: ... @property def set(self) -> ChromiumElementSetter: ... @@ -82,7 +79,7 @@ class ChromiumElement(DrissionElement): def states(self) -> ElementStates: ... @property - def location(self) -> Tuple[int, int]: ... + def location(self) -> Tuple[float, float]: ... @property def locations(self) -> Locations: ... @@ -167,12 +164,10 @@ class ChromiumElement(DrissionElement): def run_async_js(self, script: str, *args: Any, as_expr: bool = False) -> None: ... - def ele(self, - loc_or_str: Union[Tuple[str, str], str], + def ele(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> Union[ChromiumElement, str]: ... - def eles(self, - loc_or_str: Union[Tuple[str, str], str], + def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> List[Union[ChromiumElement, str]]: ... def s_ele(self, loc_or_str: Union[Tuple[str, str], str] = None) -> Union[SessionElement, str, NoneElement]: ... @@ -220,12 +215,9 @@ class ChromiumElement(DrissionElement): class ChromiumShadowRoot(BaseElement): - def __init__(self, - parent_ele: ChromiumElement, - obj_id: str = None, - backend_id: str = None): + def __init__(self, parent_ele: ChromiumElement, obj_id: str = None, backend_id: str = None): self._obj_id: str = ... - self._ids: Ids = ... + self._ids: ShadowRootIds = ... self._node_id: str = ... self._backend_id: str = ... self.page: ChromiumPage = ... @@ -234,12 +226,11 @@ class ChromiumShadowRoot(BaseElement): def __repr__(self) -> str: ... - def __call__(self, - loc_or_str: Union[Tuple[str, str], str], + def __call__(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> ChromiumElement: ... @property - def ids(self) -> Ids: ... + def ids(self) -> ShadowRootIds: ... @property def states(self) -> ShadowRootStates: ... @@ -279,12 +270,10 @@ class ChromiumShadowRoot(BaseElement): def afters(self, filter_loc: Union[tuple, str] = '') -> List[Union[ChromiumElement, str]]: ... - def ele(self, - loc_or_str: Union[Tuple[str, str], str], + def ele(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> Union[ChromiumElement]: ... - def eles(self, - loc_or_str: Union[Tuple[str, str], str], + def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> List[ChromiumElement]: ... def s_ele(self, loc_or_str: Union[Tuple[str, str], str] = None) -> Union[SessionElement, str, NoneElement]: ... @@ -303,24 +292,16 @@ class ChromiumShadowRoot(BaseElement): def _get_backend_id(self, node_id: str) -> str: ... -def find_in_chromium_ele(ele: ChromiumElement, - loc: Union[str, Tuple[str, str]], - single: bool = True, - timeout: float = None, - relative: bool = True) \ +def find_in_chromium_ele(ele: ChromiumElement, loc: Union[str, Tuple[str, str]], + single: bool = True, timeout: float = None, relative: bool = True) \ -> Union[ChromiumElement, str, NoneElement, List[Union[ChromiumElement, str]]]: ... -def find_by_xpath(ele: ChromiumElement, - xpath: str, - single: bool, - timeout: float, +def find_by_xpath(ele: ChromiumElement, xpath: str, single: bool, timeout: float, relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ... -def find_by_css(ele: ChromiumElement, - selector: str, - single: bool, +def find_by_css(ele: ChromiumElement, selector: str, single: bool, timeout: float) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ... diff --git a/DrissionPage/_pages/chromium_page.py b/DrissionPage/_pages/chromium_page.py index e6aacc4..c5fa80f 100644 --- a/DrissionPage/_pages/chromium_page.py +++ b/DrissionPage/_pages/chromium_page.py @@ -129,6 +129,8 @@ class ChromiumPage(ChromiumBase): @property def rect(self): + """返回保存窗口方位信息的对象""" + self.wait.load_complete() if self._rect is None: self._rect = TabRect(self) return self._rect diff --git a/DrissionPage/_units/clicker.py b/DrissionPage/_units/clicker.py index a64ebb5..0ab9234 100644 --- a/DrissionPage/_units/clicker.py +++ b/DrissionPage/_units/clicker.py @@ -73,7 +73,7 @@ class Clicker(object): by_js = True elif can_click and (by_js is False or not self._ele.states.is_covered): - x = int(rect[1][0] - (rect[1][0] - rect[0][0]) / 2) + x = rect[1][0] - (rect[1][0] - rect[0][0]) / 2 y = rect[0][0] + 3 try: r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=x, y=y, includeUserAgentShadowDOM=True, diff --git a/DrissionPage/_units/clicker.pyi b/DrissionPage/_units/clicker.pyi index 04ec474..10a8121 100644 --- a/DrissionPage/_units/clicker.pyi +++ b/DrissionPage/_units/clicker.pyi @@ -20,8 +20,8 @@ class Clicker(object): def middle(self) -> None: ... - def at(self, offset_x: int = None, offset_y: int = None, button: str = 'left', count: int = 1) -> None: ... + def at(self, offset_x: float = None, offset_y: float = None, button: str = 'left', count: int = 1) -> None: ... def twice(self, by_js: bool = False) -> None: ... - def _click(self, client_x: int, client_y: int, button: str = 'left', count: int = 1) -> None: ... + def _click(self, client_x: float, client_y: float, button: str = 'left', count: int = 1) -> None: ... diff --git a/DrissionPage/_units/ids.py b/DrissionPage/_units/ids.py index 5e1ee80..f5fb8d8 100644 --- a/DrissionPage/_units/ids.py +++ b/DrissionPage/_units/ids.py @@ -5,7 +5,7 @@ """ -class Ids(object): +class ShadowRootIds(object): def __init__(self, ele): self._ele = ele @@ -25,7 +25,7 @@ class Ids(object): return self._ele._backend_id -class ElementIds(Ids): +class ElementIds(ShadowRootIds): @property def doc_id(self): """返回所在document的object id""" diff --git a/DrissionPage/_units/ids.pyi b/DrissionPage/_units/ids.pyi index f224259..20d4271 100644 --- a/DrissionPage/_units/ids.pyi +++ b/DrissionPage/_units/ids.pyi @@ -9,7 +9,7 @@ from .._pages.chromium_frame import ChromiumFrame from .._elements.chromium_element import ChromiumElement, ChromiumShadowRoot -class Ids(object): +class ShadowRootIds(object): def __init__(self, ele: Union[ChromiumElement, ChromiumShadowRoot]): self._ele: Union[ChromiumElement, ChromiumShadowRoot] = ... @@ -23,7 +23,7 @@ class Ids(object): def backend_id(self) -> str: ... -class ElementIds(Ids): +class ElementIds(ShadowRootIds): @property def doc_id(self) -> str: ... diff --git a/DrissionPage/_units/locations.py b/DrissionPage/_units/locations.py index a402681..010a962 100644 --- a/DrissionPage/_units/locations.py +++ b/DrissionPage/_units/locations.py @@ -34,19 +34,19 @@ class Locations(object): def viewport_location(self): """返回元素左上角在视口中的坐标""" m = self._get_viewport_rect('border') - return int(m[0]), int(m[1]) + return m[0], m[1] @property def viewport_midpoint(self): """返回元素中间点在视口中的坐标""" m = self._get_viewport_rect('border') - return int(m[0] + (m[2] - m[0]) // 2), int(m[3] + (m[5] - m[3]) // 2) + return m[0] + (m[2] - m[0]) // 2, m[3] + (m[5] - m[3]) // 2 @property def viewport_click_point(self): """返回元素接受点击的点视口坐标""" m = self._get_viewport_rect('padding') - return int(self.viewport_midpoint[0]), int(m[1]) + 3 + return self.viewport_midpoint[0], m[1] + 3 @property def screen_location(self): @@ -54,7 +54,7 @@ class Locations(object): vx, vy = self._ele.page.rect.viewport_location ex, ey = self.viewport_location pr = self._ele.page.run_js('return window.devicePixelRatio;') - return int((vx + ex) * pr), int((ey + vy) * pr) + return (vx + ex) * pr, (ey + vy) * pr @property def screen_midpoint(self): @@ -62,7 +62,7 @@ class Locations(object): vx, vy = self._ele.page.rect.viewport_location ex, ey = self.viewport_midpoint pr = self._ele.page.run_js('return window.devicePixelRatio;') - return int((vx + ex) * pr), int((ey + vy) * pr) + return (vx + ex) * pr, (ey + vy) * pr @property def screen_click_point(self): @@ -70,15 +70,15 @@ class Locations(object): vx, vy = self._ele.page.rect.viewport_location ex, ey = self.viewport_click_point pr = self._ele.page.run_js('return window.devicePixelRatio;') - return int((vx + ex) * pr), int((ey + vy) * pr) + return (vx + ex) * pr, (ey + vy) * pr @property def rect(self): """返回元素四个角坐标,顺序:坐上、右上、右下、左下,没有大小的元素抛出NoRectError""" vr = self._get_viewport_rect('border') r = self._ele.page.run_cdp_loaded('Page.getLayoutMetrics')['visualViewport'] - sx = int(r['pageX']) - sy = int(r['pageY']) + sx = r['pageX'] + sy = r['pageY'] return [(vr[0] + sx, vr[1] + sy), (vr[2] + sx, vr[3] + sy), (vr[4] + sx, vr[5] + sy), (vr[6] + sx, vr[7] + sy)] @@ -86,7 +86,7 @@ class Locations(object): def viewport_rect(self): """返回元素四个角视口坐标,顺序:坐上、右上、右下、左下,没有大小的元素抛出NoRectError""" r = self._get_viewport_rect('border') - return [(int(r[0]), int(r[1])), (int(r[2]), int(r[3])), (int(r[4]), int(r[5])), (int(r[6]), int(r[7]))] + return [(r[0], r[1]), (r[2], r[3]), (r[4], r[5]), (r[6], r[7])] def _get_viewport_rect(self, quad): """按照类型返回在可视窗口中的范围 diff --git a/DrissionPage/_units/locations.pyi b/DrissionPage/_units/locations.pyi index 5e61165..5e7ca31 100644 --- a/DrissionPage/_units/locations.pyi +++ b/DrissionPage/_units/locations.pyi @@ -13,38 +13,38 @@ class Locations(object): self._ele: ChromiumElement = ... @property - def location(self) -> Tuple[int, int]: ... + def location(self) -> Tuple[float, float]: ... @property - def midpoint(self) -> Tuple[int, int]: ... + def midpoint(self) -> Tuple[float, float]: ... @property - def click_point(self) -> Tuple[int, int]: ... + def click_point(self) -> Tuple[float, float]: ... @property - def viewport_location(self) -> Tuple[int, int]: ... + def viewport_location(self) -> Tuple[float, float]: ... @property - def viewport_midpoint(self) -> Tuple[int, int]: ... + def viewport_midpoint(self) -> Tuple[float, float]: ... @property - def viewport_click_point(self) -> Tuple[int, int]: ... + def viewport_click_point(self) -> Tuple[float, float]: ... @property - def screen_location(self) -> Tuple[int, int]: ... + def screen_location(self) -> Tuple[float, float]: ... @property - def screen_midpoint(self) -> Tuple[int, int]: ... + def screen_midpoint(self) -> Tuple[float, float]: ... @property - def screen_click_point(self) -> Tuple[int, int]: ... + def screen_click_point(self) -> Tuple[float, float]: ... @property - def rect(self) -> List[Tuple[int, int], ...]: ... + def rect(self) -> List[Tuple[float, float], ...]: ... @property - def viewport_rect(self) -> List[Tuple[int, int], ...]: ... + def viewport_rect(self) -> List[Tuple[float, float], ...]: ... def _get_viewport_rect(self, quad: str) -> Union[list, None]: ... - def _get_page_coord(self, x: int, y: int) -> Tuple[int, int]: ... + def _get_page_coord(self, x: float, y: float) -> Tuple[float, float]: ... diff --git a/DrissionPage/_units/network_listener.py b/DrissionPage/_units/network_listener.py index 8b5d2cf..7ab0df9 100644 --- a/DrissionPage/_units/network_listener.py +++ b/DrissionPage/_units/network_listener.py @@ -190,6 +190,8 @@ class NetworkListener(object): def _requestWillBeSent(self, **kwargs): """接收到请求时的回调函数""" + if kwargs['frameId'] != self._page._frame_id: + return p = None if not self._targets: if not self._method or kwargs['request']['method'] in self._method: @@ -220,6 +222,8 @@ class NetworkListener(object): def _response_received(self, **kwargs): """接收到返回信息时处理方法""" + if kwargs['frameId'] != self._page._frame_id: + return request = self._request_ids.get(kwargs['requestId'], None) if request: request._raw_response = kwargs['response'] diff --git a/DrissionPage/_units/tab_rect.pyi b/DrissionPage/_units/tab_rect.pyi index 6b80684..d4c1223 100644 --- a/DrissionPage/_units/tab_rect.pyi +++ b/DrissionPage/_units/tab_rect.pyi @@ -6,12 +6,13 @@ from typing import Tuple, Union from .._pages.chromium_page import ChromiumPage -from .._pages.chromium_tab import ChromiumTab +from .._pages.chromium_tab import ChromiumTab, WebPageTab +from .._pages.web_page import WebPage class TabRect(object): - def __init__(self, page: Union[ChromiumPage, ChromiumTab]): - self._page: Union[ChromiumPage, ChromiumTab] = ... + def __init__(self, page: Union[ChromiumPage, ChromiumTab, WebPage, WebPageTab]): + self._page: Union[ChromiumPage, ChromiumTab, WebPage, WebPageTab] = ... @property def window_state(self) -> str: ... diff --git a/setup.py b/setup.py index 35730d9..77ed58a 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh: setup( name="DrissionPage", - version="4.0.0b7", + version="4.0.0b8", author="g1879", author_email="g1879@qq.com", description="Python based web automation tool. It can control the browser and send and receive data packets.",