mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
size、locations等合并到rect属性
This commit is contained in:
parent
a089bcbffc
commit
dbdb4528ab
@ -12,4 +12,5 @@ from ._pages.web_page import WebPage
|
||||
from ._configs.chromium_options import ChromiumOptions
|
||||
from ._configs.session_options import SessionOptions
|
||||
|
||||
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage']
|
||||
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__']
|
||||
__version__ = '4.0.0b8'
|
||||
|
@ -170,7 +170,10 @@ class Browser(object):
|
||||
end_time = perf_counter() + timeout
|
||||
while perf_counter() < end_time:
|
||||
p = popen(txt)
|
||||
if f' {self.process_id} ' not in p.read():
|
||||
try:
|
||||
if f' {self.process_id} ' not in p.read():
|
||||
return
|
||||
except TypeError:
|
||||
return
|
||||
sleep(.2)
|
||||
|
||||
|
@ -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.ids import ShadowRootIds, ElementIds
|
||||
from .._units.locations import Locations
|
||||
from .._units.rect import ElementRect
|
||||
from .._units.scroller import ElementScroller
|
||||
from .._units.select_element import SelectElement
|
||||
from .._units.setter import ChromiumElementSetter
|
||||
@ -39,7 +39,7 @@ class ChromiumElement(DrissionElement):
|
||||
super().__init__(page)
|
||||
self._select = None
|
||||
self._scroll = None
|
||||
self._locations = None
|
||||
self._rect = None
|
||||
self._set = None
|
||||
self._states = None
|
||||
self._pseudo = None
|
||||
@ -126,12 +126,6 @@ class ChromiumElement(DrissionElement):
|
||||
"""返回获取内置id的对象"""
|
||||
return self._ids
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回元素宽和高组成的元组"""
|
||||
border = self.page.run_cdp('DOM.getBoxModel', backendNodeId=self._backend_id)['model']['border']
|
||||
return border[2] - border[0], border[5] - border[1]
|
||||
|
||||
@property
|
||||
def set(self):
|
||||
"""返回用于设置元素属性的对象"""
|
||||
@ -154,16 +148,11 @@ class ChromiumElement(DrissionElement):
|
||||
return self._pseudo
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
return self.locations.location
|
||||
|
||||
@property
|
||||
def locations(self):
|
||||
def rect(self):
|
||||
"""返回用于获取元素位置的对象"""
|
||||
if self._locations is None:
|
||||
self._locations = Locations(self)
|
||||
return self._locations
|
||||
if self._rect is None:
|
||||
self._rect = ElementRect(self)
|
||||
return self._rect
|
||||
|
||||
@property
|
||||
def shadow_root(self):
|
||||
@ -565,8 +554,8 @@ class ChromiumElement(DrissionElement):
|
||||
if scroll_to_center:
|
||||
self.scroll.to_see(center=True)
|
||||
|
||||
left, top = self.location
|
||||
width, height = self.size
|
||||
left, top = self.rect.location
|
||||
width, height = self.rect.size
|
||||
left_top = (left, top)
|
||||
right_bottom = (left + width, top + height)
|
||||
if not name:
|
||||
@ -657,7 +646,7 @@ class ChromiumElement(DrissionElement):
|
||||
:param duration: 拖动用时,传入0即瞬间到j达
|
||||
:return: None
|
||||
"""
|
||||
curr_x, curr_y = self.locations.midpoint
|
||||
curr_x, curr_y = self.rect.midpoint
|
||||
offset_x += curr_x
|
||||
offset_y += curr_y
|
||||
self.drag_to((offset_x, offset_y), duration)
|
||||
@ -669,7 +658,7 @@ class ChromiumElement(DrissionElement):
|
||||
:return: None
|
||||
"""
|
||||
if isinstance(ele_or_loc, ChromiumElement):
|
||||
ele_or_loc = ele_or_loc.locations.midpoint
|
||||
ele_or_loc = ele_or_loc.rect.midpoint
|
||||
elif not isinstance(ele_or_loc, (list, tuple)):
|
||||
raise TypeError('需要ChromiumElement对象或坐标。')
|
||||
|
||||
@ -754,6 +743,18 @@ class ChromiumElement(DrissionElement):
|
||||
files = [str(Path(i).absolute()) for i in files]
|
||||
self.page.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=self._backend_id)
|
||||
|
||||
# -------------即将废弃-------------
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
return self.rect.location
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回元素宽和高组成的元组"""
|
||||
return self.rect.size
|
||||
|
||||
|
||||
class ChromiumShadowRoot(BaseElement):
|
||||
"""ChromiumShadowRoot是用于处理ShadowRoot的类,使用方法和ChromiumElement基本一致"""
|
||||
|
@ -15,7 +15,7 @@ from .._pages.chromium_page import ChromiumPage
|
||||
from .._pages.web_page import WebPage
|
||||
from .._units.clicker import Clicker
|
||||
from .._units.ids import ElementIds, ShadowRootIds
|
||||
from .._units.locations import Locations
|
||||
from .._units.rect import ElementRect
|
||||
from .._units.scroller import ElementScroller
|
||||
from .._units.select_element import SelectElement
|
||||
from .._units.setter import ChromiumElementSetter
|
||||
@ -37,7 +37,7 @@ class ChromiumElement(DrissionElement):
|
||||
self._clicker: Clicker = ...
|
||||
self._select: SelectElement = ...
|
||||
self._wait: ElementWaiter = ...
|
||||
self._locations: Locations = ...
|
||||
self._rect: ElementRect = ...
|
||||
self._set: ChromiumElementSetter = ...
|
||||
self._states: ElementStates = ...
|
||||
self._pseudo: Pseudo = ...
|
||||
@ -69,9 +69,6 @@ class ChromiumElement(DrissionElement):
|
||||
@property
|
||||
def ids(self) -> ElementIds: ...
|
||||
|
||||
@property
|
||||
def size(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def set(self) -> ChromiumElementSetter: ...
|
||||
|
||||
@ -79,10 +76,7 @@ class ChromiumElement(DrissionElement):
|
||||
def states(self) -> ElementStates: ...
|
||||
|
||||
@property
|
||||
def location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def locations(self) -> Locations: ...
|
||||
def rect(self) -> ElementRect: ...
|
||||
|
||||
@property
|
||||
def pseudo(self) -> Pseudo: ...
|
||||
|
@ -10,6 +10,7 @@ from re import findall
|
||||
from threading import Thread
|
||||
from time import perf_counter, sleep
|
||||
|
||||
from .._units.rect import TabRect
|
||||
from .._base.base import BasePage
|
||||
from .._commons.constants import ERROR, NoneElement
|
||||
from .._commons.locator import get_loc
|
||||
@ -48,6 +49,7 @@ class ChromiumBase(BasePage):
|
||||
self._states = None
|
||||
self._has_alert = False
|
||||
self._ready_state = None
|
||||
self._rect = None
|
||||
self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc
|
||||
|
||||
self._download_path = str(Path('.').absolute())
|
||||
@ -316,6 +318,14 @@ class ChromiumBase(BasePage):
|
||||
self._scroll = PageScroller(self)
|
||||
return self._scroll
|
||||
|
||||
@property
|
||||
def rect(self):
|
||||
"""返回获取窗口坐标和大小的对象"""
|
||||
# self.wait.load_complete()
|
||||
if self._rect is None:
|
||||
self._rect = TabRect(self)
|
||||
return self._rect
|
||||
|
||||
@property
|
||||
def timeouts(self):
|
||||
"""返回timeouts设置"""
|
||||
@ -373,12 +383,6 @@ class ChromiumBase(BasePage):
|
||||
"""返回当前标签页id"""
|
||||
return self.driver.id if not self.driver._stopped.is_set() else ''
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回页面总宽高,格式:(宽, 高)"""
|
||||
r = self.run_cdp_loaded('Page.getLayoutMetrics')['contentSize']
|
||||
return r['width'], r['height']
|
||||
|
||||
@property
|
||||
def active_ele(self):
|
||||
"""返回当前焦点所在元素"""
|
||||
@ -973,7 +977,7 @@ class ChromiumBase(BasePage):
|
||||
pic_type = path.suffix.lower()
|
||||
pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:]
|
||||
|
||||
width, height = self.size
|
||||
width, height = self.rect.size
|
||||
if full_page:
|
||||
vp = {'x': 0, 'y': 0, 'width': width, 'height': height, 'scale': 1}
|
||||
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type,
|
||||
@ -1030,6 +1034,11 @@ class ChromiumBase(BasePage):
|
||||
def ready_state(self):
|
||||
return self._ready_state
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回页面总宽高,格式:(宽, 高)"""
|
||||
return self.rect.size
|
||||
|
||||
|
||||
class Timeout(object):
|
||||
"""用于保存d模式timeout信息的类"""
|
||||
|
@ -6,6 +6,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Tuple, List, Any, Optional
|
||||
|
||||
from .._units.rect import TabRect
|
||||
from .._base.base import BasePage
|
||||
from .._base.browser import Browser
|
||||
from .._base.chromium_driver import ChromiumDriver
|
||||
@ -54,6 +55,7 @@ class ChromiumBase(BasePage):
|
||||
self._has_alert: bool = ...
|
||||
self._doc_got: bool = ...
|
||||
self._ready_state: Optional[str] = ...
|
||||
self._rect: TabRect = ...
|
||||
|
||||
def _connect_browser(self, tab_id: str = None) -> None: ...
|
||||
|
||||
@ -118,9 +120,6 @@ class ChromiumBase(BasePage):
|
||||
@property
|
||||
def tab_id(self) -> str: ...
|
||||
|
||||
@property
|
||||
def size(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def active_ele(self) -> ChromiumElement: ...
|
||||
|
||||
@ -133,6 +132,9 @@ class ChromiumBase(BasePage):
|
||||
@property
|
||||
def scroll(self) -> PageScroller: ...
|
||||
|
||||
@property
|
||||
def rect(self) -> TabRect: ...
|
||||
|
||||
@property
|
||||
def timeouts(self) -> Timeout: ...
|
||||
|
||||
@ -216,8 +218,8 @@ class ChromiumBase(BasePage):
|
||||
left_top: Tuple[int, int] = None, right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ...
|
||||
|
||||
def _get_screenshot(self, path: [str, Path] = None, name: str = None, as_bytes: [bool, str] = None,
|
||||
as_base64: [bool, str] = None, full_page: bool = False, left_top: Tuple[int, int] = None,
|
||||
right_bottom: Tuple[int, int] = None, ele: ChromiumElement = None) -> Union[str, bytes]: ...
|
||||
as_base64: [bool, str] = None, full_page: bool = False, left_top: Tuple[float, float] = None,
|
||||
right_bottom: Tuple[float, float] = None, ele: ChromiumElement = None) -> Union[str, bytes]: ...
|
||||
|
||||
def clear_cache(self, session_storage: bool = True, local_storage: bool = True, cache: bool = True,
|
||||
cookies: bool = True) -> None: ...
|
||||
|
@ -356,33 +356,11 @@ class ChromiumFrame(ChromiumBase):
|
||||
"""返回frame元素所有attribute属性"""
|
||||
return self.frame_ele.attrs
|
||||
|
||||
@property
|
||||
def page_size(self):
|
||||
"""返回frame内页面尺寸,格式:(长, 高)"""
|
||||
w = self.doc_ele.run_js('return this.body.scrollWidth')
|
||||
h = self.doc_ele.run_js('return this.body.scrollHeight')
|
||||
return w, h
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回frame元素大小"""
|
||||
return self.frame_ele.size
|
||||
|
||||
@property
|
||||
def active_ele(self):
|
||||
"""返回当前焦点所在元素"""
|
||||
return self.doc_ele.run_js('return this.activeElement;')
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回frame元素左上角的绝对坐标"""
|
||||
return self.frame_ele.location
|
||||
|
||||
@property
|
||||
def locations(self):
|
||||
"""返回用于获取元素位置的对象"""
|
||||
return self.frame_ele.locations
|
||||
|
||||
@property
|
||||
def xpath(self):
|
||||
"""返回frame的xpath绝对路径"""
|
||||
@ -597,8 +575,8 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
self.frame_ele.scroll.to_see(center=True)
|
||||
self.scroll.to_see(ele, center=True)
|
||||
cx, cy = ele.locations.viewport_location
|
||||
w, h = ele.size
|
||||
cx, cy = ele.rect.viewport_location
|
||||
w, h = ele.rect.size
|
||||
img_data = f'data:image/{pic_type};base64,{self.frame_ele.get_screenshot(as_base64=True)}'
|
||||
body = self.tab('t:body')
|
||||
first_child = body('c::first-child')
|
||||
@ -652,3 +630,23 @@ class ChromiumFrame(ChromiumBase):
|
||||
def is_alive(self):
|
||||
"""返回是否仍可用"""
|
||||
return self.states.is_alive
|
||||
|
||||
@property
|
||||
def page_size(self):
|
||||
"""返回frame内页面尺寸,格式:(宽,, 高)"""
|
||||
return self.rect.size
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回frame元素大小"""
|
||||
return self.frame_ele.rect.size
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回frame元素左上角的绝对坐标"""
|
||||
return self.frame_ele.rect.location
|
||||
|
||||
@property
|
||||
def locations(self):
|
||||
"""返回用于获取元素位置的对象"""
|
||||
return self.frame_ele.rect
|
||||
|
@ -13,7 +13,6 @@ from .web_page import WebPage
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
from .._units.states import FrameStates
|
||||
from .._units.ids import FrameIds
|
||||
from .._units.locations import Locations
|
||||
from .._units.rect import FrameRect
|
||||
from .._units.scroller import FrameScroller
|
||||
from .._units.setter import ChromiumFrameSetter
|
||||
@ -89,24 +88,12 @@ class ChromiumFrame(ChromiumBase):
|
||||
@property
|
||||
def attrs(self) -> dict: ...
|
||||
|
||||
@property
|
||||
def page_size(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def size(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def rect(self) -> FrameRect: ...
|
||||
|
||||
@property
|
||||
def active_ele(self) -> ChromiumElement: ...
|
||||
|
||||
@property
|
||||
def location(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def locations(self) -> Locations: ...
|
||||
|
||||
@property
|
||||
def xpath(self) -> str: ...
|
||||
|
||||
|
@ -13,7 +13,6 @@ from .._commons.browser import connect_browser
|
||||
from .._configs.chromium_options import ChromiumOptions
|
||||
from .._pages.chromium_base import ChromiumBase, Timeout
|
||||
from .._pages.chromium_tab import ChromiumTab
|
||||
from .._units.rect import TabRect
|
||||
from .._units.setter import ChromiumPageSetter
|
||||
from .._units.waiter import PageWaiter
|
||||
from ..errors import BrowserConnectError
|
||||
@ -104,14 +103,6 @@ class ChromiumPage(ChromiumBase):
|
||||
self._set = ChromiumPageSetter(self)
|
||||
return self._set
|
||||
|
||||
@property
|
||||
def rect(self):
|
||||
"""返回保存窗口方位信息的对象"""
|
||||
self.wait.load_complete()
|
||||
if self._rect is None:
|
||||
self._rect = TabRect(self)
|
||||
return self._rect
|
||||
|
||||
@property
|
||||
def wait(self):
|
||||
"""返回用于等待的对象"""
|
||||
|
@ -39,9 +39,6 @@ class ChromiumPage(ChromiumBase):
|
||||
@property
|
||||
def tabs(self) -> List[str]: ...
|
||||
|
||||
@property
|
||||
def rect(self) -> TabRect: ...
|
||||
|
||||
@property
|
||||
def wait(self) -> PageWaiter: ...
|
||||
|
||||
|
@ -9,7 +9,6 @@ from .._base.base import BasePage
|
||||
from .._commons.web import set_session_cookies, set_browser_cookies
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
from .._pages.session_page import SessionPage
|
||||
from .._units.rect import TabRect
|
||||
from .._units.setter import TabSetter, WebPageTabSetter
|
||||
from .._units.waiter import TabWaiter
|
||||
|
||||
@ -44,13 +43,6 @@ class ChromiumTab(ChromiumBase):
|
||||
"""返回总体page对象"""
|
||||
return self._page
|
||||
|
||||
@property
|
||||
def rect(self):
|
||||
"""返回获取窗口坐标和大小的对象"""
|
||||
if self._rect is None:
|
||||
self._rect = TabRect(self)
|
||||
return self._rect
|
||||
|
||||
@property
|
||||
def set(self):
|
||||
"""返回用于等待的对象"""
|
||||
|
@ -34,9 +34,6 @@ class ChromiumTab(ChromiumBase):
|
||||
@property
|
||||
def page(self) -> ChromiumPage: ...
|
||||
|
||||
@property
|
||||
def rect(self) -> TabRect: ...
|
||||
|
||||
@property
|
||||
def set(self) -> TabSetter: ...
|
||||
|
||||
|
@ -49,6 +49,13 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
|
||||
elif self._mode == 's':
|
||||
return super().__call__(loc_or_str)
|
||||
|
||||
@property
|
||||
def set(self):
|
||||
"""返回用于等待的对象"""
|
||||
if self._set is None:
|
||||
self._set = WebPageSetter(self)
|
||||
return self._set
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
"""返回当前url"""
|
||||
@ -134,13 +141,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
|
||||
"""
|
||||
self.set.timeouts(implicit=second)
|
||||
|
||||
@property
|
||||
def set(self):
|
||||
"""返回用于等待的对象"""
|
||||
if self._set is None:
|
||||
self._set = WebPageSetter(self)
|
||||
return self._set
|
||||
|
||||
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs):
|
||||
"""跳转到一个url
|
||||
:param url: 目标url
|
||||
|
@ -39,7 +39,7 @@ class ActionChains:
|
||||
elif isinstance(ele_or_loc, str) or 'ChromiumElement' in str(type(ele_or_loc)):
|
||||
ele_or_loc = self.page(ele_or_loc)
|
||||
self.page.scroll.to_see(ele_or_loc)
|
||||
x, y = ele_or_loc.location if offset_x or offset_y else ele_or_loc.locations.midpoint
|
||||
x, y = ele_or_loc.rect.location if offset_x or offset_y else ele_or_loc.rect.midpoint
|
||||
lx = x + offset_x
|
||||
ly = y + offset_y
|
||||
else:
|
||||
@ -55,8 +55,8 @@ class ActionChains:
|
||||
if is_loc:
|
||||
cx, cy = location_to_client(self.page, lx, ly)
|
||||
else:
|
||||
x, y = ele_or_loc.locations.viewport_location if offset_x or offset_y \
|
||||
else ele_or_loc.locations.viewport_midpoint
|
||||
x, y = ele_or_loc.rect.viewport_location if offset_x or offset_y \
|
||||
else ele_or_loc.rect.viewport_midpoint
|
||||
cx = x + offset_x
|
||||
cy = y + offset_y
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Clicker(object):
|
||||
try:
|
||||
self._ele.scroll.to_see()
|
||||
if self._ele.states.is_enabled and self._ele.states.is_displayed:
|
||||
rect = self._ele.locations.viewport_rect
|
||||
rect = self._ele.rect.viewport_corners
|
||||
can_click = True
|
||||
except NoRectError:
|
||||
if by_js is False:
|
||||
@ -59,7 +59,7 @@ class Clicker(object):
|
||||
self._ele.wait.stop_moving(timeout=end_time - perf_counter())
|
||||
if rect:
|
||||
self._ele.scroll.to_see()
|
||||
rect = self._ele.locations.rect
|
||||
rect = self._ele.rect.corners
|
||||
while perf_counter() < end_time:
|
||||
if self._ele.states.is_enabled and self._ele.states.is_displayed:
|
||||
can_click = True
|
||||
@ -79,12 +79,12 @@ class Clicker(object):
|
||||
r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=x, y=y, includeUserAgentShadowDOM=True,
|
||||
ignorePointerEventsNone=True)
|
||||
if r['backendNodeId'] != self._ele.ids.backend_id:
|
||||
vx, vy = self._ele.locations.viewport_midpoint
|
||||
vx, vy = self._ele.rect.viewport_midpoint
|
||||
else:
|
||||
vx, vy = self._ele.locations.viewport_click_point
|
||||
vx, vy = self._ele.rect.viewport_click_point
|
||||
|
||||
except CDPError:
|
||||
vx, vy = self._ele.locations.viewport_midpoint
|
||||
vx, vy = self._ele.rect.viewport_midpoint
|
||||
|
||||
self._click(vx, vy)
|
||||
return True
|
||||
@ -99,13 +99,13 @@ class Clicker(object):
|
||||
def right(self):
|
||||
"""右键单击"""
|
||||
self._ele.page.scroll.to_see(self._ele)
|
||||
x, y = self._ele.locations.viewport_click_point
|
||||
x, y = self._ele.rect.viewport_click_point
|
||||
self._click(x, y, 'right')
|
||||
|
||||
def middle(self):
|
||||
"""中键单击"""
|
||||
self._ele.page.scroll.to_see(self._ele)
|
||||
x, y = self._ele.locations.viewport_click_point
|
||||
x, y = self._ele.rect.viewport_click_point
|
||||
self._click(x, y, 'middle')
|
||||
|
||||
def at(self, offset_x=None, offset_y=None, button='left', count=1):
|
||||
@ -118,7 +118,7 @@ class Clicker(object):
|
||||
"""
|
||||
self._ele.page.scroll.to_see(self._ele)
|
||||
if offset_x is None and offset_y is None:
|
||||
w, h = self._ele.size
|
||||
w, h = self._ele.rect.size
|
||||
offset_x = w // 2
|
||||
offset_y = h // 2
|
||||
x, y = offset_scroll(self._ele, offset_x, offset_y)
|
||||
|
@ -1,103 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
"""
|
||||
|
||||
|
||||
class Locations(object):
|
||||
def __init__(self, ele):
|
||||
"""
|
||||
:param ele: ChromiumElement
|
||||
"""
|
||||
self._ele = ele
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
cl = self.viewport_location
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def midpoint(self):
|
||||
"""返回元素中间点的绝对坐标"""
|
||||
cl = self.viewport_midpoint
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def click_point(self):
|
||||
"""返回元素接受点击的点的绝对坐标"""
|
||||
cl = self.viewport_click_point
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def viewport_location(self):
|
||||
"""返回元素左上角在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
return m[0], m[1]
|
||||
|
||||
@property
|
||||
def viewport_midpoint(self):
|
||||
"""返回元素中间点在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
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 self.viewport_midpoint[0], m[1] + 3
|
||||
|
||||
@property
|
||||
def screen_location(self):
|
||||
"""返回元素左上角在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_location
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
return (vx + ex) * pr, (ey + vy) * pr
|
||||
|
||||
@property
|
||||
def screen_midpoint(self):
|
||||
"""返回元素中点在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_midpoint
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
return (vx + ex) * pr, (ey + vy) * pr
|
||||
|
||||
@property
|
||||
def screen_click_point(self):
|
||||
"""返回元素中点在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_click_point
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
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 = 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)]
|
||||
|
||||
@property
|
||||
def viewport_rect(self):
|
||||
"""返回元素四个角视口坐标,顺序:坐上、右上、右下、左下,没有大小的元素抛出NoRectError"""
|
||||
r = self._get_viewport_rect('border')
|
||||
return [(r[0], r[1]), (r[2], r[3]), (r[4], r[5]), (r[6], r[7])]
|
||||
|
||||
def _get_viewport_rect(self, quad):
|
||||
"""按照类型返回在可视窗口中的范围
|
||||
:param quad: 方框类型,margin border padding
|
||||
:return: 四个角坐标
|
||||
"""
|
||||
return self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele.ids.backend_id)['model'][quad]
|
||||
|
||||
def _get_page_coord(self, x, y):
|
||||
"""根据视口坐标获取绝对坐标"""
|
||||
r = self._ele.page.run_cdp_loaded('Page.getLayoutMetrics')['visualViewport']
|
||||
sx = r['pageX']
|
||||
sy = r['pageY']
|
||||
return x + sx, y + sy
|
@ -1,50 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
"""
|
||||
from typing import Tuple, Union, List
|
||||
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
|
||||
|
||||
class Locations(object):
|
||||
def __init__(self, ele: ChromiumElement):
|
||||
self._ele: ChromiumElement = ...
|
||||
|
||||
@property
|
||||
def location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def rect(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
||||
@property
|
||||
def viewport_rect(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
||||
def _get_viewport_rect(self, quad: str) -> Union[list, None]: ...
|
||||
|
||||
def _get_page_coord(self, x: float, y: float) -> Tuple[float, float]: ...
|
@ -5,6 +5,110 @@
|
||||
"""
|
||||
|
||||
|
||||
class ElementRect(object):
|
||||
def __init__(self, ele):
|
||||
"""
|
||||
:param ele: ChromiumElement
|
||||
"""
|
||||
self._ele = ele
|
||||
|
||||
@property
|
||||
def corners(self):
|
||||
"""返回元素四个角坐标,顺序:坐上、右上、右下、左下,没有大小的元素抛出NoRectError"""
|
||||
vr = self._get_viewport_rect('border')
|
||||
r = self._ele.page.run_cdp_loaded('Page.getLayoutMetrics')['visualViewport']
|
||||
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)]
|
||||
|
||||
@property
|
||||
def viewport_corners(self):
|
||||
"""返回元素四个角视口坐标,顺序:坐上、右上、右下、左下,没有大小的元素抛出NoRectError"""
|
||||
r = self._get_viewport_rect('border')
|
||||
return [(r[0], r[1]), (r[2], r[3]), (r[4], r[5]), (r[6], r[7])]
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回元素大小,格式(宽, 高)"""
|
||||
border = self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id)['model']['border']
|
||||
return border[2] - border[0], border[5] - border[1]
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
cl = self.viewport_location
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def midpoint(self):
|
||||
"""返回元素中间点的绝对坐标"""
|
||||
cl = self.viewport_midpoint
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def click_point(self):
|
||||
"""返回元素接受点击的点的绝对坐标"""
|
||||
cl = self.viewport_click_point
|
||||
return self._get_page_coord(cl[0], cl[1])
|
||||
|
||||
@property
|
||||
def viewport_location(self):
|
||||
"""返回元素左上角在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
return m[0], m[1]
|
||||
|
||||
@property
|
||||
def viewport_midpoint(self):
|
||||
"""返回元素中间点在视口中的坐标"""
|
||||
m = self._get_viewport_rect('border')
|
||||
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 self.viewport_midpoint[0], m[1] + 3
|
||||
|
||||
@property
|
||||
def screen_location(self):
|
||||
"""返回元素左上角在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_location
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
return (vx + ex) * pr, (ey + vy) * pr
|
||||
|
||||
@property
|
||||
def screen_midpoint(self):
|
||||
"""返回元素中点在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_midpoint
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
return (vx + ex) * pr, (ey + vy) * pr
|
||||
|
||||
@property
|
||||
def screen_click_point(self):
|
||||
"""返回元素中点在屏幕上坐标,左上角为(0, 0)"""
|
||||
vx, vy = self._ele.page.rect.viewport_location
|
||||
ex, ey = self.viewport_click_point
|
||||
pr = self._ele.page.run_js('return window.devicePixelRatio;')
|
||||
return (vx + ex) * pr, (ey + vy) * pr
|
||||
|
||||
def _get_viewport_rect(self, quad):
|
||||
"""按照类型返回在可视窗口中的范围
|
||||
:param quad: 方框类型,margin border padding
|
||||
:return: 四个角坐标
|
||||
"""
|
||||
return self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele.ids.backend_id)['model'][quad]
|
||||
|
||||
def _get_page_coord(self, x, y):
|
||||
"""根据视口坐标获取绝对坐标"""
|
||||
r = self._ele.page.run_cdp_loaded('Page.getLayoutMetrics')['visualViewport']
|
||||
sx = r['pageX']
|
||||
sy = r['pageY']
|
||||
return x + sx, y + sy
|
||||
|
||||
|
||||
class TabRect(object):
|
||||
def __init__(self, page):
|
||||
self._page = page
|
||||
@ -49,7 +153,7 @@ class TabRect(object):
|
||||
return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs
|
||||
|
||||
@property
|
||||
def page_size(self):
|
||||
def size(self):
|
||||
"""返回页面总宽高,格式:(宽, 高)"""
|
||||
r = self._get_page_rect()['contentSize']
|
||||
return r['width'], r['height']
|
||||
@ -83,21 +187,38 @@ class FrameRect(object):
|
||||
self._frame = frame
|
||||
|
||||
@property
|
||||
def viewport_location(self):
|
||||
"""返回视口在屏幕中坐标,左上角为(0, 0)"""
|
||||
return self._frame.frame_ele.locations.screen_location
|
||||
def location(self):
|
||||
"""返回元素左上角的绝对坐标"""
|
||||
return self._frame.frame_ele.rect.location
|
||||
|
||||
@property
|
||||
def page_size(self):
|
||||
"""返回页面总宽高,格式:(宽, 高)"""
|
||||
return self._frame.page_size
|
||||
def viewport_location(self):
|
||||
"""返回视口在屏幕中坐标,左上角为(0, 0)"""
|
||||
return self._frame.frame_ele.rect.viewport_location
|
||||
|
||||
@property
|
||||
def screen_location(self):
|
||||
"""返回元素左上角在屏幕上坐标,左上角为(0, 0)"""
|
||||
return self._frame.frame_ele.rect.screen_location
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""返回页面总宽高,格式:(宽, 高)"""
|
||||
return self._frame.size
|
||||
"""返回frame内页面尺寸,格式:(宽, 高)"""
|
||||
w = self._frame.doc_ele.run_js('return this.body.scrollWidth')
|
||||
h = self._frame.doc_ele.run_js('return this.body.scrollHeight')
|
||||
return w, h
|
||||
|
||||
@property
|
||||
def viewport_size(self):
|
||||
"""返回视口宽高,不包括滚动条,格式:(宽, 高)"""
|
||||
return self._frame.frame_ele.size
|
||||
"""返回视口宽高,格式:(宽, 高)"""
|
||||
return self._frame.frame_ele.rect.size
|
||||
|
||||
@property
|
||||
def corners(self):
|
||||
"""返回元素四个角坐标,顺序:坐上、右上、右下、左下"""
|
||||
return self._frame.frame_ele.rect.corners
|
||||
|
||||
@property
|
||||
def viewport_corners(self):
|
||||
"""返回元素四个角视口坐标,顺序:坐上、右上、右下、左下"""
|
||||
return self._frame.frame_ele.rect.viewport_corners
|
||||
|
@ -3,16 +3,64 @@
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
"""
|
||||
from typing import Tuple, Union
|
||||
|
||||
from typing import Tuple, Union, List
|
||||
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
from .._pages.chromium_frame import ChromiumFrame
|
||||
from .._pages.chromium_page import ChromiumPage
|
||||
from .._pages.chromium_tab import ChromiumTab, WebPageTab
|
||||
from .._pages.web_page import WebPage
|
||||
|
||||
|
||||
class ElementRect(object):
|
||||
def __init__(self, ele: ChromiumElement):
|
||||
self._ele: ChromiumElement = ...
|
||||
|
||||
@property
|
||||
def size(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_midpoint(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_click_point(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def corners(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
||||
@property
|
||||
def viewport_corners(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
||||
def _get_viewport_rect(self, quad: str) -> Union[list, None]: ...
|
||||
|
||||
def _get_page_coord(self, x: float, y: float) -> Tuple[float, float]: ...
|
||||
|
||||
|
||||
class TabRect(object):
|
||||
def __init__(self, page: Union[ChromiumPage, ChromiumTab, WebPage, WebPageTab]):
|
||||
def __init__(self, page: ChromiumBase):
|
||||
self._page: Union[ChromiumPage, ChromiumTab, WebPage, WebPageTab] = ...
|
||||
|
||||
@property
|
||||
@ -31,7 +79,7 @@ class TabRect(object):
|
||||
def window_size(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def page_size(self) -> Tuple[int, int]: ...
|
||||
def size(self) -> Tuple[int, int]: ...
|
||||
|
||||
@property
|
||||
def viewport_size(self) -> Tuple[int, int]: ...
|
||||
@ -48,14 +96,23 @@ class FrameRect(object):
|
||||
def __init__(self, frame: ChromiumFrame):
|
||||
self._frame: ChromiumFrame = ...
|
||||
|
||||
@property
|
||||
def location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def screen_location(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def size(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def page_size(self) -> Tuple[float, float]: ...
|
||||
def viewport_size(self) -> Tuple[float, float]: ...
|
||||
|
||||
@property
|
||||
def viewport_size(self) -> Tuple[float, float]: ...
|
||||
def corners(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
||||
@property
|
||||
def viewport_corners(self) -> List[Tuple[float, float], ...]: ...
|
||||
|
@ -48,21 +48,21 @@ class ElementStates(object):
|
||||
@property
|
||||
def is_in_viewport(self):
|
||||
"""返回元素是否出现在视口中,以元素click_point为判断"""
|
||||
x, y = self._ele.locations.click_point
|
||||
x, y = self._ele.rect.click_point
|
||||
return location_in_viewport(self._ele.page, x, y) if x else False
|
||||
|
||||
@property
|
||||
def is_whole_in_viewport(self):
|
||||
"""返回元素是否整个都在视口内"""
|
||||
x1, y1 = self._ele.location
|
||||
w, h = self._ele.size
|
||||
x1, y1 = self._ele.rect.location
|
||||
w, h = self._ele.rect.size
|
||||
x2, y2 = x1 + w, y1 + h
|
||||
return location_in_viewport(self._ele.page, x1, y1) and location_in_viewport(self._ele.page, x2, y2)
|
||||
|
||||
@property
|
||||
def is_covered(self):
|
||||
"""返回元素是否被覆盖,与是否在视口中无关"""
|
||||
lx, ly = self._ele.locations.click_point
|
||||
lx, ly = self._ele.rect.click_point
|
||||
try:
|
||||
r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=lx, y=ly)
|
||||
except CDPError:
|
||||
@ -77,7 +77,7 @@ class ElementStates(object):
|
||||
def has_rect(self):
|
||||
"""返回元素是否拥有位置和大小,没有返回False,有返回四个角在页面中坐标组成的列表"""
|
||||
try:
|
||||
return self._ele.locations.rect
|
||||
return self._ele.rect.corners
|
||||
except NoRectError:
|
||||
return False
|
||||
|
||||
|
@ -376,7 +376,7 @@ class ElementWaiter(object):
|
||||
while perf_counter() < end_time:
|
||||
try:
|
||||
size = self._ele.states.has_rect
|
||||
location = self._ele.location
|
||||
location = self._ele.rect.location
|
||||
break
|
||||
except NoRectError:
|
||||
pass
|
||||
@ -385,10 +385,10 @@ class ElementWaiter(object):
|
||||
|
||||
while perf_counter() < end_time:
|
||||
sleep(gap)
|
||||
if self._ele.size == size and location == self._ele.location:
|
||||
if self._ele.rect.size == size and location == self._ele.rect.location:
|
||||
return True
|
||||
size = self._ele.size
|
||||
location = self._ele.location
|
||||
size = self._ele.rect.size
|
||||
location = self._ele.rect.location
|
||||
|
||||
if raise_err is True or Settings.raise_when_wait_failed is True:
|
||||
raise WaitTimeoutError('等待元素停止运动失败。')
|
||||
|
Loading…
x
Reference in New Issue
Block a user