修复drag()方法定位不准问题;位置和大小改为以tuple方式返回;完善make_session_ele();改进类型注解

This commit is contained in:
g1879 2022-12-21 17:46:30 +08:00
parent 0e0e34868e
commit 3a2d0c9f18
8 changed files with 129 additions and 131 deletions

View File

@ -30,9 +30,9 @@ class ActionChains:
lx = ele_or_loc[0] + offset_x
ly = ele_or_loc[1] + offset_y
elif 'ChromiumElement' in str(type(ele_or_loc)):
ele_loc = ele_or_loc.location if offset_x or offset_y else ele_or_loc.midpoint
lx = ele_loc['x'] + offset_x
ly = ele_loc['y'] + offset_y
x, y = ele_or_loc.location if offset_x or offset_y else ele_or_loc.midpoint
lx = x + offset_x
ly = y + offset_y
else:
raise TypeError('ele_or_loc参数只能接受坐标(x, y)或ChromiumElement对象。')

View File

@ -18,33 +18,33 @@ class ActionChains:
self.modifier: int = ...
def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[int, int]],
offset_x: int = ..., offset_y: int = ...) -> 'ActionChains': ...
offset_x: int = ..., offset_y: int = ...) -> ActionChains: ...
def move(self, offset_x: int = ..., offset_y: int = ...) -> 'ActionChains': ...
def move(self, offset_x: int = ..., offset_y: int = ...) -> ActionChains: ...
def hold(self, on_ele:ChromiumElement=...) -> 'ActionChains': ...
def hold(self, on_ele:ChromiumElement=...) -> ActionChains: ...
def click(self, on_ele:ChromiumElement=...) -> 'ActionChains': ...
def click(self, on_ele:ChromiumElement=...) -> ActionChains: ...
def r_click(self, on_ele:ChromiumElement=...) -> 'ActionChains': ...
def r_click(self, on_ele:ChromiumElement=...) -> ActionChains: ...
def release(self, on_ele:ChromiumElement=...) -> 'ActionChains': ...
def release(self, on_ele:ChromiumElement=...) -> ActionChains: ...
def scroll(self, delta_x: int = ..., delta_y: int = ..., on_ele:ChromiumElement=...) -> 'ActionChains': ...
def scroll(self, delta_x: int = ..., delta_y: int = ..., on_ele:ChromiumElement=...) -> ActionChains: ...
def up(self, pixel: int) -> 'ActionChains': ...
def up(self, pixel: int) -> ActionChains: ...
def down(self, pixel: int) -> 'ActionChains': ...
def down(self, pixel: int) -> ActionChains: ...
def left(self, pixel: int) -> 'ActionChains': ...
def left(self, pixel: int) -> ActionChains: ...
def right(self, pixel: int) -> 'ActionChains': ...
def right(self, pixel: int) -> ActionChains: ...
def key_down(self, key:str) -> 'ActionChains': ...
def key_down(self, key:str) -> ActionChains: ...
def key_up(self, key:str) -> 'ActionChains': ...
def key_up(self, key:str) -> ActionChains: ...
def wait(self, second: float) -> 'ActionChains': ...
def wait(self, second: float) -> ActionChains: ...
def _get_key_data(self, key:str, action: str) -> dict: ...

View File

@ -2,20 +2,17 @@
"""
@Author : g1879
@Contact : g1879@qq.com
@File : chromium_element.py
"""
from os import sep
from os.path import basename
from pathlib import Path
from re import search
from time import perf_counter, sleep
from urllib.parse import urlparse
from .base import DrissionElement, BaseElement
from .common import make_absolute_link, get_loc, get_ele_txt, format_html, is_js_func, _location_in_viewport
from .keys import _keys_to_typing, _keyDescriptionForString, _keyDefinitions
from .session_element import make_session_ele
from .chromium_frame import ChromiumFrame
class ChromiumElement(DrissionElement):
@ -61,7 +58,8 @@ class ChromiumElement(DrissionElement):
def tag(self):
"""返回元素tag"""
if self._tag is None:
self._tag = self.page.run_cdp('DOM.describeNode', nodeId=self._node_id)['node']['localName'].lower()
self._tag = self.page.run_cdp('DOM.describeNode', nodeId=self._node_id, not_change=True)['node'][
'localName'].lower()
return self._tag
@property
@ -69,11 +67,11 @@ class ChromiumElement(DrissionElement):
"""返回元素outerHTML文本"""
tag = self.tag
if tag in ('iframe', 'frame'):
out_html = self.page.run_cdp('DOM.getOuterHTML', nodeId=self._node_id)['outerHTML']
out_html = self.page.run_cdp('DOM.getOuterHTML', nodeId=self._node_id, not_change=True)['outerHTML']
in_html = self.inner_html
sign = search(rf'<{tag}.*?>', out_html).group(0)
return f'{sign}{in_html}</{tag}>'
return self.page.run_cdp('DOM.getOuterHTML', nodeId=self._node_id)['outerHTML']
return self.page.run_cdp('DOM.getOuterHTML', nodeId=self._node_id, not_change=True)['outerHTML']
@property
def inner_html(self):
@ -86,7 +84,7 @@ class ChromiumElement(DrissionElement):
@property
def attrs(self):
"""返回元素所有attribute属性"""
attrs = self.page.run_cdp('DOM.getAttributes', nodeId=self._node_id)['attributes']
attrs = self.page.run_cdp('DOM.getAttributes', nodeId=self._node_id, not_change=True)['attributes']
attrs_len = len(attrs)
return {attrs[i]: attrs[i + 1] for i in range(0, attrs_len, 2)}
@ -120,51 +118,51 @@ class ChromiumElement(DrissionElement):
def size(self):
"""返回元素宽和高"""
try:
model = self.page.run_cdp('DOM.getBoxModel', nodeId=self._node_id)['model']
return {'height': model['height'], 'width': model['width']}
model = self.page.run_cdp('DOM.getBoxModel', nodeId=self._node_id, not_change=True)['model']
return model['height'], model['width']
except Exception:
return {'height': 0, 'width': 0}
return 0, 0
@property
def client_location(self):
"""返回元素左上角在视口中的坐标"""
m = self._get_client_rect('border')
return {'x': m[0], 'y': m[1]} if m else None
return (m[0], m[1]) if m else (0, 0)
@property
def client_midpoint(self):
"""返回元素中间点在视口中的坐标"""
m = self._get_client_rect('border')
return {'x': m[2] - m[0], 'y': m[5] - m[1]} if m else None
return (m[0] + (m[2] - m[0]) // 2, m[3] + (m[5] - m[3]) // 2) if m else (0, 0)
@property
def location(self):
"""返回元素左上角的绝对坐标"""
cl = self.client_location
return self._get_absolute_rect(cl['x'], cl['y']) if cl else None
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0)
@property
def midpoint(self):
"""返回元素中间点的绝对坐标"""
cl = self.client_midpoint
return self._get_absolute_rect(cl['x'], cl['y']) if cl else None
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0)
@property
def _client_click_point(self):
"""返回元素左上角可接受点击的点视口坐标"""
m = self._get_client_rect('padding')
return {'x': m[0], 'y': m[1]} if m else None
return (m[0], m[1]) if m else (0, 0)
@property
def _click_point(self):
"""返回元素左上角可接受点击的点的绝对坐标"""
cl = self._client_click_point
return self._get_absolute_rect(cl['x'], cl['y']) if cl else None
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0)
@property
def shadow_root(self):
"""返回当前元素的shadow_root元素对象"""
info = self.page.run_cdp('DOM.describeNode', nodeId=self.node_id)['node']
info = self.page.run_cdp('DOM.describeNode', nodeId=self.node_id, not_change=True)['node']
if not info.get('shadowRoots', None):
return None
@ -307,8 +305,8 @@ class ChromiumElement(DrissionElement):
@property
def is_in_viewport(self):
"""返回元素是否出现在视口中,以元素可以接受点击的点为判断"""
loc = self.location
return _location_in_viewport(self.page, loc['x'], loc['y']) if loc else False
x, y = self.location
return _location_in_viewport(self.page, x, y) if x else False
def attr(self, attr):
"""返回attribute属性值 \n
@ -361,7 +359,7 @@ class ChromiumElement(DrissionElement):
:param prop: 属性名
:return: 属性值文本
"""
p = self.page.run_cdp('Runtime.getProperties', objectId=self._obj_id)['result']
p = self.page.run_cdp('Runtime.getProperties', objectId=self._obj_id, not_change=True)['result']
for i in p:
if i['name'] == prop:
if 'value' not in i or 'value' not in i['value']:
@ -392,7 +390,7 @@ class ChromiumElement(DrissionElement):
:param args: 参数按顺序在js文本中对应argument[0]argument[2]...
:return: 运行的结果
"""
return run_script(self, script, as_expr, self.page.timeouts.script, args)
return run_script(self, script, as_expr, self.page.timeouts.script, args, True)
def run_async_script(self, script, as_expr=False, *args):
"""以异步方式执行js代码 \n
@ -402,7 +400,7 @@ class ChromiumElement(DrissionElement):
:return: None
"""
from threading import Thread
Thread(target=run_script, args=(self, script, as_expr, self.page.timeouts.script, args)).start()
Thread(target=run_script, args=(self, script, as_expr, self.page.timeouts.script, args, True)).start()
def ele(self, loc_or_str, timeout=None):
"""返回当前元素下级符合条件的第一个元素、属性或节点文本 \n
@ -472,7 +470,7 @@ class ChromiumElement(DrissionElement):
while not self.run_script(js) and perf_counter() < end_time:
sleep(.1)
node = self.page.run_cdp('DOM.describeNode', nodeId=self._node_id)['node']
node = self.page.run_cdp('DOM.describeNode', nodeId=self._node_id, not_change=True)['node']
frame = node.get('frameId', None)
frame = frame or self.page.tab_id
try:
@ -519,8 +517,8 @@ class ChromiumElement(DrissionElement):
while not self.run_script(js) and perf_counter() < end_time:
sleep(.1)
left, top = self.location.values()
height, width = self.size.values()
left, top = self.location
height, width = self.size
left_top = (left, top)
right_bottom = (left + width, top + height)
return self.page.get_screenshot(path, as_bytes=as_bytes, full_page=False,
@ -536,7 +534,7 @@ class ChromiumElement(DrissionElement):
return self._set_file_input(vals)
try:
self.page.run_cdp('DOM.focus', nodeId=self._node_id)
self.page.run_cdp('DOM.focus', nodeId=self._node_id, not_change=True)
except Exception:
self.click(by_js=True)
@ -566,7 +564,7 @@ class ChromiumElement(DrissionElement):
"""
if isinstance(files, str):
files = files.split('\n')
self.page.run_cdp('DOM.setFileInputFiles', files=files, nodeId=self._node_id)
self.page.run_cdp('DOM.setFileInputFiles', files=files, nodeId=self._node_id, not_change=True)
def clear(self, by_js=False):
"""清空元素文本 \n
@ -604,13 +602,9 @@ class ChromiumElement(DrissionElement):
if not by_js:
self.page.scroll_to_see(self)
if self.is_in_viewport:
client_point = self._client_click_point
if client_point:
loc_point = self._click_point
client_x = client_point['x']
client_y = client_point['y']
loc_x = loc_point['x']
loc_y = loc_point['y']
client_x, client_y = self._client_click_point
if client_x:
loc_x, loc_y = self._click_point
click = do_it(client_x, client_y, loc_x, loc_y)
if click:
@ -643,8 +637,8 @@ class ChromiumElement(DrissionElement):
def r_click(self):
"""右键单击"""
self.page.scroll_to_see(self)
xy = self._client_click_point
self._click(xy['x'], xy['y'], 'right')
x, y = self._client_click_point
self._click(x, y, 'right')
def r_click_at(self, offset_x=None, offset_y=None):
"""带偏移量右键单击本元素相对于左上角坐标。不传入x或y值时点击元素中点 \n
@ -683,9 +677,9 @@ class ChromiumElement(DrissionElement):
:param shake: 是否随机抖动
:return: None
"""
curr_xy = self.midpoint
offset_x += curr_xy['x']
offset_y += curr_xy['y']
curr_x, curr_y = self.midpoint
offset_x += curr_x
offset_y += curr_y
self.drag_to((offset_x, offset_y), speed, shake)
def drag_to(self, ele_or_loc, speed=40, shake=True):
@ -697,17 +691,13 @@ class ChromiumElement(DrissionElement):
"""
# x, y目标点坐标
if isinstance(ele_or_loc, ChromiumElement):
midpoint = ele_or_loc.midpoint
target_x = midpoint['x']
target_y = midpoint['y']
target_x, target_y = ele_or_loc.midpoint
elif isinstance(ele_or_loc, (list, tuple)):
target_x, target_y = ele_or_loc
else:
raise TypeError('需要ChromiumElement对象或坐标。')
curr_xy = self.midpoint
current_x = curr_xy['x']
current_y = curr_xy['y']
current_x, current_y = self.midpoint
width = target_x - current_x
height = target_y - current_y
num = 0 if not speed else int(((abs(width) ** 2 + abs(height) ** 2) ** .5) // speed)
@ -735,14 +725,14 @@ class ChromiumElement(DrissionElement):
:param node_id: cdp中的node id
:return: js中的object id
"""
return self.page.run_cdp('DOM.resolveNode', nodeId=node_id)['object']['objectId']
return self.page.run_cdp('DOM.resolveNode', nodeId=node_id, not_change=True)['object']['objectId']
def _get_node_id(self, obj_id):
"""根据传入object id获取cdp中的node id \n
:param obj_id: js中的object id
:return: cdp中的node id
"""
return self.page.run_cdp('DOM.requestNode', objectId=obj_id)['nodeId']
return self.page.run_cdp('DOM.requestNode', objectId=obj_id, not_change=True)['nodeId']
def _get_ele_path(self, mode):
"""返获取css路径或xpath路径"""
@ -787,12 +777,12 @@ class ChromiumElement(DrissionElement):
return f':root{t}' if mode == 'css' else t
def _get_client_rect(self, quad):
"""按照类型返回坐标
"""按照类型返回窗口坐标 \n
:param quad: 方框类型margin border padding
:return: 四个角坐标大小为0时返回None
"""
try:
return self.page.run_cdp('DOM.getBoxModel', nodeId=self.node_id)['model'][quad]
return self.page.run_cdp('DOM.getBoxModel', nodeId=self.node_id, not_change=True)['model'][quad]
except:
return None
@ -845,7 +835,7 @@ class ChromiumShadowRootElement(BaseElement):
def is_alive(self):
"""返回元素是否仍在DOM中"""
try:
self.page.run_cdp('DOM.describeNode', nodeId=self._node_id)
self.page.run_cdp('DOM.describeNode', nodeId=self._node_id, not_change=True)
return True
except Exception:
return False
@ -1030,28 +1020,30 @@ class ChromiumShadowRootElement(BaseElement):
css_paths = [i.css_path[47:] for i in eles]
if single:
node_id = self.page.run_cdp('DOM.querySelector', nodeId=self._node_id, selector=css_paths[0])['nodeId']
return ChromiumElement(self.page, node_id) if node_id else None
node_id = self.page.run_cdp('DOM.querySelector',
nodeId=self._node_id, selector=css_paths[0], not_change=True)['nodeId']
return _make_chromium_ele(self.page, node_id=node_id) if node_id else None
else:
results = []
for i in css_paths:
node_id = self.page.run_cdp('DOM.querySelector', nodeId=self._node_id, selector=i)['nodeId']
node_id = self.page.run_cdp('DOM.querySelector',
nodeId=self._node_id, selector=i, not_change=True)['nodeId']
if node_id:
results.append(ChromiumElement(self.page, node_id))
results.append(_make_chromium_ele(self.page, node_id=node_id))
return results
def _get_node_id(self, obj_id):
"""返回元素node id"""
return self.page.run_cdp('DOM.requestNode', objectId=obj_id)['nodeId']
return self.page.run_cdp('DOM.requestNode', objectId=obj_id, not_change=True)['nodeId']
def _get_obj_id(self, back_id):
"""返回元素object id"""
return self.page.run_cdp('DOM.resolveNode', backendNodeId=back_id)['object']['objectId']
return self.page.run_cdp('DOM.resolveNode', backendNodeId=back_id, not_change=True)['object']['objectId']
def _get_backend_id(self, node_id):
"""返回元素object id"""
return self.page.run_cdp('DOM.describeNode', nodeId=node_id)['node']['backendNodeId']
return self.page.run_cdp('DOM.describeNode', nodeId=node_id, not_change=True)['node']['backendNodeId']
def make_chromium_ele(ele, loc, single=True, timeout=None, relative=True):
@ -1179,14 +1171,9 @@ def _find_by_css(ele, selector, single, timeout):
def _make_chromium_ele(page, node_id=None, obj_id=None):
"""根据node id或object id生成相应元素对象"""
ele = ChromiumElement(page, obj_id=obj_id, node_id=node_id)
if ele.tag in ('iframe', 'frame') and ele.attr('src'):
src = ele.attr('src')
if src:
netloc1 = urlparse(src).netloc
netloc2 = urlparse(page.url).netloc
if netloc1 != netloc2:
# from .chromium_base import ChromiumFrame
ele = ChromiumFrame(page, ele)
if ele.tag in ('iframe', 'frame'):
from .chromium_frame import ChromiumFrame
ele = ChromiumFrame(page, ele)
return ele
@ -1232,13 +1219,14 @@ else{a.push(e.snapshotItem(i));}}"""
return js
def run_script(page_or_ele, script, as_expr=False, timeout=None, args=None):
def run_script(page_or_ele, script, as_expr=False, timeout=None, args=None, not_change=False):
"""运行javascript代码 \n
:param page_or_ele: 页面对象或元素对象
:param script: js文本
:param as_expr: 是否作为表达式运行为True时args无效
:param timeout: 超时时间
:param args: 参数按顺序在js文本中对应argument[0]argument[2]...
:param not_change: 执行时是否切换页面对象模式
:return: js执行结果
"""
if isinstance(page_or_ele, (ChromiumElement, ChromiumShadowRootElement)):
@ -1257,7 +1245,9 @@ def run_script(page_or_ele, script, as_expr=False, timeout=None, args=None):
returnByValue=False,
awaitPromise=True,
userGesture=True,
timeout=timeout * 1000)
timeout=timeout * 1000,
not_change=not_change)
else:
args = args or ()
if not is_js_func(script):
@ -1268,7 +1258,8 @@ def run_script(page_or_ele, script, as_expr=False, timeout=None, args=None):
arguments=[_convert_argument(arg) for arg in args],
returnByValue=False,
awaitPromise=True,
userGesture=True)
userGesture=True,
not_change=not_change)
exceptionDetails = res.get('exceptionDetails')
if exceptionDetails:

View File

@ -7,11 +7,12 @@
from pathlib import Path
from typing import Union, Tuple, List, Any
from .chromium_base import ChromiumBase
from .chromium_page import ChromiumPage
from .web_page import WebPage
from .base import DrissionElement, BaseElement
from .chromium_base import ChromiumBase
from .chromium_frame import ChromiumFrame
from .chromium_page import ChromiumPage
from .session_element import SessionElement
from .web_page import WebPage
class ChromiumElement(DrissionElement):
@ -33,7 +34,7 @@ class ChromiumElement(DrissionElement):
def __call__(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, ChromiumFrame, str, None]: ...
@property
def tag(self) -> str: ...
@ -64,31 +65,31 @@ class ChromiumElement(DrissionElement):
def doc_id(self) -> str: ...
@property
def size(self) -> dict: ...
def size(self) -> tuple: ...
@property
def client_location(self) -> Union[dict, None]: ...
def client_location(self) -> tuple: ...
@property
def client_midpoint(self) -> Union[dict, None]: ...
def client_midpoint(self) -> tuple: ...
@property
def location(self) -> Union[dict, None]: ...
def location(self) -> tuple: ...
@property
def midpoint(self) -> dict: ...
def midpoint(self) -> tuple: ...
@property
def _client_click_point(self) -> Union[dict, None]: ...
def _client_click_point(self) -> tuple: ...
@property
def _click_point(self) -> Union[dict, None]: ...
def _click_point(self) -> tuple: ...
@property
def shadow_root(self) -> Union[None, 'ChromiumShadowRootElement']: ...
def shadow_root(self) -> Union[None, ChromiumShadowRootElement]: ...
@property
def sr(self): ...
def sr(self) -> Union[None, ChromiumShadowRootElement]: ...
@property
def pseudo_before(self) -> str: ...
@ -97,44 +98,44 @@ class ChromiumElement(DrissionElement):
def pseudo_after(self) -> str: ...
@property
def scroll(self) -> 'ChromeScroll': ...
def scroll(self) -> ChromeScroll: ...
def parent(self, level_or_loc: Union[tuple, str, int] = ...) -> Union['ChromiumElement', None]: ...
def parent(self, level_or_loc: Union[tuple, str, int] = ...) -> Union[ChromiumElement, None]: ...
def prev(self,
filter_loc: Union[tuple, str] = ...,
index: int = ...,
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, str, None]: ...
def next(self,
filter_loc: Union[tuple, str] = ...,
index: int = ...,
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, str, None]: ...
def before(self,
filter_loc: Union[tuple, str] = ...,
index: int = ...,
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, str, None]: ...
def after(self,
filter_loc: Union[tuple, str] = ...,
index: int = ...,
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, str, None]: ...
def prevs(self,
filter_loc: Union[tuple, str] = ...,
timeout: float = ...) -> List[Union['ChromiumElement', str]]: ...
timeout: float = ...) -> List[Union[ChromiumElement, str]]: ...
def nexts(self,
filter_loc: Union[tuple, str] = ...,
timeout: float = ...) -> List[Union['ChromiumElement', str]]: ...
timeout: float = ...) -> List[Union[ChromiumElement, str]]: ...
def befores(self,
filter_loc: Union[tuple, str] = ...,
timeout: float = ...) -> List[Union['ChromiumElement', str]]: ...
timeout: float = ...) -> List[Union[ChromiumElement, str]]: ...
def wait_ele(self,
loc_or_ele: Union[str, tuple, 'ChromiumElement'],
loc_or_ele: Union[str, tuple, ChromiumElement],
timeout: float = ...) -> 'ChromiumElementWaiter': ...
@property
@ -173,11 +174,11 @@ class ChromiumElement(DrissionElement):
def ele(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> Union['ChromiumElement', str, None]: ...
timeout: float = ...) -> Union[ChromiumElement, ChromiumFrame, str, None]: ...
def eles(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> List[Union['ChromiumElement', str]]: ...
timeout: float = ...) -> List[Union[ChromiumElement, ChromiumFrame, str]]: ...
def s_ele(self, loc_or_str: Union[Tuple[str, str], str] = ...) -> Union[SessionElement, str, None]: ...
@ -186,7 +187,7 @@ class ChromiumElement(DrissionElement):
def _ele(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ..., single: bool = ..., relative: bool = ...) \
-> Union['ChromiumElement', str, None, List[Union['ChromiumElement', str]]]: ...
-> Union[ChromiumElement, ChromiumFrame, str, None, List[Union[ChromiumElement, ChromiumFrame, str]]]: ...
def style(self, style: str, pseudo_ele: str = ...) -> str: ...
@ -217,7 +218,7 @@ class ChromiumElement(DrissionElement):
def drag(self, offset_x: int = ..., offset_y: int = ..., speed: int = ..., shake: bool = ...) -> None: ...
def drag_to(self,
ele_or_loc: Union[tuple, 'ChromiumElement'],
ele_or_loc: Union[tuple, ChromiumElement],
speed: int = ...,
shake: bool = ...) -> None: ...
@ -248,7 +249,7 @@ class ChromiumShadowRootElement(BaseElement):
def __call__(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> Union[ChromiumElement, None]: ...
timeout: float = ...) -> Union[ChromiumElement, ChromiumFrame, None]: ...
@property
def is_enabled(self) -> bool: ...
@ -297,20 +298,21 @@ class ChromiumShadowRootElement(BaseElement):
def ele(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> Union[ChromiumElement, None]: ...
timeout: float = ...) -> Union[ChromiumElement, ChromiumFrame, None]: ...
def eles(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> List[ChromiumElement]: ...
timeout: float = ...) -> List[Union[ChromiumElement, ChromiumFrame]]: ...
def s_ele(self, loc_or_str: Union[Tuple[str, str], str] = ...) -> Union[SessionElement, str, None]: ...
def s_eles(self, loc_or_str: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
def s_eles(self, loc_or_str: Union[Tuple[str, str], str]) -> List[Union[SessionElement, str]]: ...
def _ele(self,
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...,
single: bool = ..., relative: bool = ...) -> Union['ChromiumElement', None, List[ChromiumElement]]: ...
single: bool = ..., relative: bool = ...) \
-> Union[ChromiumElement, ChromiumFrame, None, str, List[Union[ChromiumElement, ChromiumFrame, str]]]: ...
def _get_node_id(self, obj_id: str) -> str: ...
@ -346,8 +348,7 @@ def _make_js_for_find_ele_by_xpath(xpath: str, type_txt: str, node_txt: str) ->
def run_script(page_or_ele: Union[ChromiumBase, ChromiumElement, ChromiumShadowRootElement], script: str,
as_expr: bool = ...,
timeout: float = ..., args: tuple = ...) -> Any: ...
as_expr: bool = ..., timeout: float = ..., args: tuple = ..., not_change:bool=...) -> Any: ...
def _parse_js_result(page: ChromiumBase, ele: ChromiumElement, result: dict): ...

View File

@ -149,9 +149,9 @@ class ChromiumPage(ChromiumBase):
raise TypeError(f'不支持的文件格式:{pic_type}')
pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:]
hw = self.size
width, height = self.size
if full_page:
vp = {'x': 0, 'y': 0, 'width': hw['width'], 'height': hw['height'], 'scale': 1}
vp = {'x': 0, 'y': 0, 'width': width, 'height': height, 'scale': 1}
png = self._wait_driver.Page.captureScreenshot(format=pic_type, captureBeyondViewport=True, clip=vp)['data']
else:
if left_top and right_bottom:

View File

@ -264,7 +264,8 @@ def make_session_ele(html_or_ele, loc=None, single=True):
raise ValueError("定位符必须为str或长度为2的tuple。")
# ---------------根据传入对象类型获取页面对象和lxml元素对象---------------
if isinstance(html_or_ele, SessionElement): # SessionElement
the_type = str(type(html_or_ele))
if the_type.endswith(".SessionElement'>"): # SessionElement
page = html_or_ele.page
loc_str = loc[1]
@ -285,7 +286,7 @@ def make_session_ele(html_or_ele, loc=None, single=True):
loc = loc[0], loc_str
elif isinstance(html_or_ele, DrissionElement): # ChromiumElement, DriverElement
elif the_type.endswith((".ChromiumElement'>", ".DriverElement'>")): # ChromiumElement, DriverElement
loc_str = loc[1]
if loc[0] == 'xpath' and loc[1].lstrip().startswith('/'):
loc_str = f'.{loc[1]}'
@ -296,14 +297,14 @@ def make_session_ele(html_or_ele, loc=None, single=True):
# 获取整个页面html再定位到当前元素以实现查找上级元素
page = html_or_ele.page
xpath = html_or_ele.xpath
if hasattr(html_or_ele, 'doc_id'): # ChromiumElement支持元素在iframe内的情况
if hasattr(html_or_ele, 'doc_id'): # ChromiumElement兼容传入的元素在iframe内的情况
html = html_or_ele.page.run_cdp('DOM.getOuterHTML', objectId=html_or_ele.doc_id)['outerHTML']
else:
html = html_or_ele.page.html
html_or_ele = fromstring(html)
html_or_ele = html_or_ele.xpath(xpath)[0]
elif isinstance(html_or_ele, BasePage): # MixPage, DriverPage 或 SessionPage
elif isinstance(html_or_ele, BasePage): # 各种页面对象
page = html_or_ele
html_or_ele = fromstring(html_or_ele.html)
@ -311,7 +312,8 @@ def make_session_ele(html_or_ele, loc=None, single=True):
page = None
html_or_ele = fromstring(html_or_ele)
elif isinstance(html_or_ele, BaseElement): # ShadowRootElement
# ShadowRootElement, ChromiumShadowRootElement, ChromiumFrame
elif isinstance(html_or_ele, BaseElement) or the_type.endswith(".ChromiumFrame'>"):
page = html_or_ele.page
html_or_ele = fromstring(html_or_ele.html)

View File

@ -3,7 +3,10 @@ from typing import Union, List, Tuple
from lxml.html import HtmlElement
from .base import DrissionElement, BasePage, BaseElement
from .base import DrissionElement, BaseElement
from .chromium_base import ChromiumFrame, ChromiumBase
from .chromium_element import ChromiumElement
from .driver_element import DriverElement
from .session_page import SessionPage
@ -104,6 +107,7 @@ class SessionElement(DrissionElement):
def _get_ele_path(self, mode: str) -> str: ...
def make_session_ele(html_or_ele: Union[str, BaseElement, BasePage],
def make_session_ele(html_or_ele: Union[str, SessionElement, ChromiumElement, DriverElement, BaseElement, ChromiumFrame,
ChromiumBase],
loc: Union[str, Tuple[str, str]] = ...,
single: bool = ...) -> Union[SessionElement, str, None, List[Union[SessionElement, str]]]: ...

View File

@ -5,8 +5,8 @@ from DownloadKit import DownloadKit
from requests import Session, Response
from .base import BasePage
from .chromium_base import ChromiumFrame
from .chromium_element import ChromiumElement
from .chromium_frame import ChromiumFrame
from .chromium_page import ChromiumPage
from .config import DriverOptions, SessionOptions
from .session_element import SessionElement
@ -99,7 +99,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
loc_or_str: Union[Tuple[str, str], str],
timeout: float = ...) -> List[Union[ChromiumElement, SessionElement, ChromiumFrame, str]]: ...
def s_ele(self, loc_or_ele: Union[Tuple[str, str], str, ChromiumElement, SessionElement] = ...) \
def s_ele(self, loc_or_ele: Union[Tuple[str, str], str] = ...) \
-> Union[SessionElement, str, None]: ...
def s_eles(self, loc_or_str: Union[Tuple[str, str], str] = ...) -> List[Union[SessionElement, str]]: ...
@ -147,7 +147,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def download(self) -> DownloadKit: ...
def _ele(self,
loc_or_ele: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
loc_or_ele: Union[Tuple[str, str], str, ChromiumElement, SessionElement, ChromiumFrame],
timeout: float = ..., single: bool = ..., relative: bool = ...) \
-> Union[ChromiumElement, SessionElement, ChromiumFrame, str, None, List[Union[SessionElement, str]], List[
Union[ChromiumElement, str, ChromiumFrame]]]: ...