插件路径自动变成绝对路径;抓包加上判断frame;元素坐标改为float;修复配置文件损坏时出现的问题

This commit is contained in:
g1879 2023-11-14 11:41:33 +08:00
parent a5e86167e2
commit 47557844e0
14 changed files with 68 additions and 77 deletions

View File

@ -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]

View File

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

View File

@ -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):

View File

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

View File

@ -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

View File

@ -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,

View File

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

View File

@ -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"""

View File

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

View File

@ -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):
"""按照类型返回在可视窗口中的范围

View File

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

View File

@ -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']

View File

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

View File

@ -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.",