ChromiumElement状态、伪元素、位置、设置api整合;ChromiumPage位置大小属性整合;增加获取元素和视口屏幕坐标功能

This commit is contained in:
g1879 2023-02-16 18:20:27 +08:00
parent 1fccb9eeb8
commit ffaf534934
13 changed files with 564 additions and 200 deletions

View File

@ -38,7 +38,7 @@ class ActionChains:
elif isinstance(ele_or_loc, str) or 'ChromiumElement' in str(type(ele_or_loc)): elif isinstance(ele_or_loc, str) or 'ChromiumElement' in str(type(ele_or_loc)):
ele_or_loc = self.page(ele_or_loc) ele_or_loc = self.page(ele_or_loc)
self.page.scroll.to_see(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.midpoint x, y = ele_or_loc.location if offset_x or offset_y else ele_or_loc.locations.midpoint
lx = x + offset_x lx = x + offset_x
ly = y + offset_y ly = y + offset_y
else: else:
@ -54,7 +54,8 @@ class ActionChains:
if is_loc: if is_loc:
cx, cy = location_to_client(self.page, lx, ly) cx, cy = location_to_client(self.page, lx, ly)
else: else:
x, y = ele_or_loc.client_location if offset_x or offset_y else ele_or_loc.client_midpoint x, y = ele_or_loc.locations.viewport_location if offset_x or offset_y \
else ele_or_loc.locations.viewport_midpoint
cx = x + offset_x cx = x + offset_x
cy = y + offset_y cy = y + offset_y

View File

@ -77,6 +77,7 @@ class ChromiumBase(BasePage):
self._is_reading = False self._is_reading = False
self._upload_list = None self._upload_list = None
self._wait = None self._wait = None
self._scroll = None
def _driver_init(self, tab_id): def _driver_init(self, tab_id):
"""新建页面、页面刷新、切换标签页后要进行的cdp参数初始化 """新建页面、页面刷新、切换标签页后要进行的cdp参数初始化
@ -296,7 +297,7 @@ class ChromiumBase(BasePage):
def scroll(self): def scroll(self):
"""返回用于滚动滚动条的对象""" """返回用于滚动滚动条的对象"""
self.wait.load_complete() self.wait.load_complete()
if not hasattr(self, '_scroll'): if self._scroll is None:
self._scroll = ChromiumPageScroll(self) self._scroll = ChromiumPageScroll(self)
return self._scroll return self._scroll
@ -685,12 +686,13 @@ class ChromiumBase(BasePage):
return True return True
# ------------------准备废弃----------------------
def wait_loading(self, timeout=None): def wait_loading(self, timeout=None):
"""阻塞程序,等待页面进入加载状态 """阻塞程序,等待页面进入加载状态
:param timeout: 超时时间 :param timeout: 超时时间
:return: 等待结束时是否进入加载状态 :return: 等待结束时是否进入加载状态
""" """
warn("方法即将弃用请用wait.load_start()方法代替。", DeprecationWarning) warn("wait_loading()方法即将弃用请用wait.load_start()方法代替。", DeprecationWarning)
return self.wait.load_start(timeout) return self.wait.load_start(timeout)
def wait_ele(self, loc_or_ele, timeout=None): def wait_ele(self, loc_or_ele, timeout=None):
@ -699,7 +701,7 @@ class ChromiumBase(BasePage):
:param timeout: 等待超时时间 :param timeout: 等待超时时间
:return: 用于等待的ElementWaiter对象 :return: 用于等待的ElementWaiter对象
""" """
warn("方法即将弃用请用wait.ele_xxxx()方法代替。", DeprecationWarning) warn("wait_ele()方法即将弃用请用wait.ele_xxxx()方法代替。", DeprecationWarning)
return ChromiumElementWaiter(self, loc_or_ele, timeout) return ChromiumElementWaiter(self, loc_or_ele, timeout)
def scroll_to_see(self, loc_or_ele): def scroll_to_see(self, loc_or_ele):
@ -707,7 +709,7 @@ class ChromiumBase(BasePage):
:param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串详见ele函数注释 :param loc_or_ele: 元素的定位信息可以是loc元组或查询字符串详见ele函数注释
:return: None :return: None
""" """
warn("方法即将弃用请用scroll.to_see()方法代替。", DeprecationWarning) warn("scroll_to_see()方法即将弃用请用scroll.to_see()方法代替。", DeprecationWarning)
self.scroll.to_see(loc_or_ele) self.scroll.to_see(loc_or_ele)
def set_timeouts(self, implicit=None, page_load=None, script=None): def set_timeouts(self, implicit=None, page_load=None, script=None):
@ -717,7 +719,7 @@ class ChromiumBase(BasePage):
:param script: 脚本运行超时时间 :param script: 脚本运行超时时间
:return: None :return: None
""" """
warn("方法即将弃用请用set.timeouts()方法代替。", DeprecationWarning) warn("set_timeouts()方法即将弃用请用set.timeouts()方法代替。", DeprecationWarning)
self.set.timeouts(implicit, page_load, script) self.set.timeouts(implicit, page_load, script)
def set_session_storage(self, item, value): def set_session_storage(self, item, value):
@ -726,7 +728,7 @@ class ChromiumBase(BasePage):
:param value: 项的值设置为False时删除该项 :param value: 项的值设置为False时删除该项
:return: None :return: None
""" """
warn("方法即将弃用请用set.session_storage()方法代替。", DeprecationWarning) warn("set_session_storage()方法即将弃用请用set.session_storage()方法代替。", DeprecationWarning)
return self.set.session_storage(item, value) return self.set.session_storage(item, value)
def set_local_storage(self, item, value): def set_local_storage(self, item, value):
@ -735,7 +737,7 @@ class ChromiumBase(BasePage):
:param value: 项的值设置为False时删除该项 :param value: 项的值设置为False时删除该项
:return: None :return: None
""" """
warn("方法即将弃用请用set.local_storage()方法代替。", DeprecationWarning) warn("set_local_storage()方法即将弃用请用set.local_storage()方法代替。", DeprecationWarning)
return self.set.local_storage(item, value) return self.set.local_storage(item, value)
def set_user_agent(self, ua, platform=None): def set_user_agent(self, ua, platform=None):
@ -744,7 +746,7 @@ class ChromiumBase(BasePage):
:param platform: platform字符串 :param platform: platform字符串
:return: None :return: None
""" """
warn("方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning) warn("set_user_agent()方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning)
self.set.user_agent(ua, platform) self.set.user_agent(ua, platform)
def set_cookies(self, cookies): def set_cookies(self, cookies):
@ -752,7 +754,7 @@ class ChromiumBase(BasePage):
:param cookies: cookies信息 :param cookies: cookies信息
:return: None :return: None
""" """
warn("方法即将弃用请用set.cookies()方法代替。", DeprecationWarning) warn("set_cookies()方法即将弃用请用set.cookies()方法代替。", DeprecationWarning)
self.set.cookies(cookies) self.set.cookies(cookies)
def set_upload_files(self, files): def set_upload_files(self, files):
@ -760,7 +762,7 @@ class ChromiumBase(BasePage):
:param files: 文件路径列表或字符串字符串时多个文件用回车分隔 :param files: 文件路径列表或字符串字符串时多个文件用回车分隔
:return: None :return: None
""" """
warn("方法即将弃用请用set.upload_files()方法代替。", DeprecationWarning) warn("set_upload_files()方法即将弃用请用set.upload_files()方法代替。", DeprecationWarning)
self.set.upload_files(files) self.set.upload_files(files)
def set_headers(self, headers: dict) -> None: def set_headers(self, headers: dict) -> None:
@ -768,13 +770,13 @@ class ChromiumBase(BasePage):
:param headers: dict格式的headers数据 :param headers: dict格式的headers数据
:return: None :return: None
""" """
warn("方法即将弃用请用set.headers()方法代替。", DeprecationWarning) warn("set_headers()方法即将弃用请用set.headers()方法代替。", DeprecationWarning)
self.set.headers(headers) self.set.headers(headers)
@property @property
def set_page_load_strategy(self): def set_page_load_strategy(self):
"""返回用于设置页面加载策略的对象""" """返回用于设置页面加载策略的对象"""
warn("方法即将弃用请用set.load_strategy.xxxx()方法代替。", DeprecationWarning) warn("set_page_load_strategy()方法即将弃用请用set.load_strategy.xxxx()方法代替。", DeprecationWarning)
return self.set.load_strategy return self.set.load_strategy
@ -926,7 +928,7 @@ class ChromiumPageScroll(ChromiumScroll):
except Exception: except Exception:
ele.run_js("this.scrollIntoView();") ele.run_js("this.scrollIntoView();")
if not ele.is_in_viewport: if not ele.states.is_in_viewport:
offset_scroll(ele, 0, 0) offset_scroll(ele, 0, 0)

View File

@ -11,7 +11,7 @@ from warnings import warn
from .base import DrissionElement, BaseElement from .base import DrissionElement, BaseElement
from .common.constants import FRAME_ELEMENT, NoneElement from .common.constants import FRAME_ELEMENT, NoneElement
from .common.errors import ContextLossError, ElementLossError, CallMethodError from .common.errors import ContextLossError, ElementLossError, CallMethodError, JavaScriptError
from .common.locator import get_loc from .common.locator import get_loc
from .common.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll from .common.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll
from .keys import _keys_to_typing, _keyDescriptionForString, _keyDefinitions from .keys import _keys_to_typing, _keyDescriptionForString, _keyDefinitions
@ -31,6 +31,10 @@ class ChromiumElement(DrissionElement):
super().__init__(page) super().__init__(page)
self._select = None self._select = None
self._scroll = None self._scroll = None
self._locations = None
self._set = None
self._states = None
self._pseudo = None
self._click = None self._click = None
self._tag = None self._tag = None
self._wait = None self._wait = None
@ -131,40 +135,37 @@ class ChromiumElement(DrissionElement):
return 0, 0 return 0, 0
@property @property
def client_location(self): def set(self):
"""返回元素左上角在视口中的坐标""" """返回用于设置元素属性的对象"""
m = self._get_client_rect('border') if self._set is None:
return (int(m[0]), int(m[1])) if m else (0, 0) self._set = ChromiumElementSetter(self)
return self._set
@property @property
def client_midpoint(self): def states(self):
"""返回元素中间点在视口中的坐标""" """返回用于获取元素状态的对象"""
m = self._get_client_rect('border') if self._states is None:
return (int(m[0] + (m[2] - m[0]) // 2), int(m[3] + (m[5] - m[3]) // 2)) if m else (0, 0) self._states = ChromiumElementStates(self)
return self._states
@property
def pseudo(self):
"""返回用于获取伪元素内容的对象"""
if self._pseudo is None:
self._pseudo = Pseudo(self)
return self._pseudo
@property @property
def location(self): def location(self):
"""返回元素左上角的绝对坐标""" """返回元素左上角的绝对坐标"""
cl = self.client_location return self.locations.page_location
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0)
@property @property
def midpoint(self): def locations(self):
"""返回元素中间点的绝对坐标""" """返回用于获取元素位置的对象"""
cl = self.client_midpoint if self._locations is None:
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0) self._locations = Locations(self)
return self._locations
@property
def _client_click_point(self):
"""返回元素左上角可接受点击的点视口坐标"""
m = self._get_client_rect('padding')
return (int(self.client_midpoint[0]), int(m[1]) + 1) if m else (0, 0)
@property
def _click_point(self):
"""返回元素左上角可接受点击的点的绝对坐标"""
cl = self._client_click_point
return self._get_absolute_rect(cl[0], cl[1]) if cl else (0, 0)
@property @property
def shadow_root(self): def shadow_root(self):
@ -180,16 +181,6 @@ class ChromiumElement(DrissionElement):
"""返回当前元素的shadow_root元素对象""" """返回当前元素的shadow_root元素对象"""
return self.shadow_root return self.shadow_root
@property
def pseudo_before(self):
"""返回当前元素的::before伪元素内容"""
return self.style('content', 'before')
@property
def pseudo_after(self):
"""返回当前元素的::after伪元素内容"""
return self.style('content', 'after')
@property @property
def scroll(self): def scroll(self):
"""用于滚动滚动条的对象""" """用于滚动滚动条的对象"""
@ -204,6 +195,24 @@ class ChromiumElement(DrissionElement):
self._click = Click(self) self._click = Click(self)
return self._click return self._click
@property
def wait(self):
"""返回用于等待的对象"""
if self._wait is None:
self._wait = ChromiumWaiter(self)
return self._wait
@property
def select(self):
"""返回专门处理下拉列表的Select类非下拉列表元素返回False"""
if self._select is None:
if self.tag != 'select':
self._select = False
else:
self._select = ChromiumSelect(self)
return self._select
def parent(self, level_or_loc=1): def parent(self, level_or_loc=1):
"""返回上面某一级父元素,可指定层数或用查询语法定位 """返回上面某一级父元素,可指定层数或用查询语法定位
:param level_or_loc: 第几级父元素或定位符 :param level_or_loc: 第几级父元素或定位符
@ -279,56 +288,6 @@ class ChromiumElement(DrissionElement):
""" """
return super().afters(filter_loc, timeout) return super().afters(filter_loc, timeout)
@property
def wait(self):
"""返回用于等待的对象"""
if self._wait is None:
self._wait = ChromiumWaiter(self)
return self._wait
@property
def select(self):
"""返回专门处理下拉列表的Select类非下拉列表元素返回False"""
if self._select is None:
if self.tag != 'select':
self._select = False
else:
self._select = ChromiumSelect(self)
return self._select
@property
def is_selected(self):
"""返回元素是否被选择"""
return self.run_js('return this.selected;')
@property
def is_displayed(self):
"""返回元素是否显示"""
return not (self.style('visibility') == 'hidden'
or self.run_js('return this.offsetParent === null;')
or self.style('display') == 'none')
@property
def is_enabled(self):
"""返回元素是否可用"""
return not self.run_js('return this.disabled;')
@property
def is_alive(self):
"""返回元素是否仍在DOM中"""
try:
d = self.attrs
return True
except Exception:
return False
@property
def is_in_viewport(self):
"""返回元素是否出现在视口中,以元素可以接受点击的点为判断"""
x, y = self._click_point
return location_in_viewport(self.page, x, y) if x else False
def attr(self, attr): def attr(self, attr):
"""返回attribute属性值 """返回attribute属性值
:param attr: 属性名 :param attr: 属性名
@ -360,14 +319,6 @@ class ChromiumElement(DrissionElement):
else: else:
return attrs.get(attr, None) return attrs.get(attr, None)
def set_attr(self, attr, value):
"""设置元素attribute属性
:param attr: 属性名
:param value: 属性值
:return: None
"""
self.page.run_cdp('DOM.setAttributeValue', nodeId=self.node_id, name=attr, value=str(value))
def remove_attr(self, attr): def remove_attr(self, attr):
"""删除元素attribute属性 """删除元素attribute属性
:param attr: 属性名 :param attr: 属性名
@ -388,22 +339,6 @@ class ChromiumElement(DrissionElement):
return format_html(i['value']['value']) return format_html(i['value']['value'])
def set_prop(self, prop, value):
"""设置元素property属性
:param prop: 属性名
:param value: 属性值
:return: None
"""
value = value.replace('"', r'\"')
self.run_js(f'this.{prop}="{value}";')
def set_innerHTML(self, html):
"""设置元素innerHTML
:param html: html文本
:return: None
"""
self.set_prop('innerHTML', html)
def run_js(self, script, as_expr=False, *args): def run_js(self, script, as_expr=False, *args):
"""运行javascript代码 """运行javascript代码
:param script: js文本 :param script: js文本
@ -580,16 +515,6 @@ class ChromiumElement(DrissionElement):
else: else:
self.page.run_cdp('Input.insertText', text=vals) self.page.run_cdp('Input.insertText', text=vals)
def _set_file_input(self, files):
"""往上传控件写入路径
:param files: 文件路径列表或字符串字符串时多个文件用回车分隔
:return: None
"""
if isinstance(files, str):
files = files.split('\n')
files = [str(Path(i).absolute()) for i in files]
self.page.run_cdp('DOM.setFileInputFiles', files=files, nodeId=self._node_id)
def clear(self, by_js=False): def clear(self, by_js=False):
"""清空元素文本 """清空元素文本
:param by_js: 是否用js方式清空 :param by_js: 是否用js方式清空
@ -619,7 +544,7 @@ class ChromiumElement(DrissionElement):
:param shake: 是否随机抖动 :param shake: 是否随机抖动
:return: None :return: None
""" """
curr_x, curr_y = self.midpoint curr_x, curr_y = self.locations.midpoint
offset_x += curr_x offset_x += curr_x
offset_y += curr_y offset_y += curr_y
self.drag_to((offset_x, offset_y), speed, shake) self.drag_to((offset_x, offset_y), speed, shake)
@ -633,13 +558,13 @@ class ChromiumElement(DrissionElement):
""" """
# x, y目标点坐标 # x, y目标点坐标
if isinstance(ele_or_loc, ChromiumElement): if isinstance(ele_or_loc, ChromiumElement):
target_x, target_y = ele_or_loc.midpoint target_x, target_y = ele_or_loc.locations.midpoint
elif isinstance(ele_or_loc, (list, tuple)): elif isinstance(ele_or_loc, (list, tuple)):
target_x, target_y = ele_or_loc target_x, target_y = ele_or_loc
else: else:
raise TypeError('需要ChromiumElement对象或坐标。') raise TypeError('需要ChromiumElement对象或坐标。')
current_x, current_y = self.midpoint current_x, current_y = self.locations.midpoint
width = target_x - current_x width = target_x - current_x
height = target_y - current_y height = target_y - current_y
num = 0 if not speed else int(((abs(width) ** 2 + abs(height) ** 2) ** .5) // speed) num = 0 if not speed else int(((abs(width) ** 2 + abs(height) ** 2) ** .5) // speed)
@ -732,22 +657,17 @@ class ChromiumElement(DrissionElement):
t = self.run_js(js) t = self.run_js(js)
return f':root{t}' if mode == 'css' else t return f':root{t}' if mode == 'css' else t
def _get_client_rect(self, quad): def _set_file_input(self, files):
"""按照类型返回窗口坐标 """往上传控件写入路径
:param quad: 方框类型margin border padding :param files: 文件路径列表或字符串字符串时多个文件用回车分隔
:return: 四个角坐标大小为0时返回None :return: None
""" """
try: if isinstance(files, str):
return self.page.run_cdp('DOM.getBoxModel', nodeId=self.node_id)['model'][quad] files = files.split('\n')
except CallMethodError: files = [str(Path(i).absolute()) for i in files]
return None self.page.run_cdp('DOM.setFileInputFiles', files=files, nodeId=self._node_id)
def _get_absolute_rect(self, x, y): # ---------------准备废弃-----------------
"""根据绝对坐标获取窗口坐标"""
js = 'return document.documentElement.scrollLeft+" "+document.documentElement.scrollTop;'
xy = self.run_js(js)
sx, sy = xy.split(' ')
return int(x + float(sx)), int(y + float(sy))
def wait_ele(self, loc_or_ele, timeout=None): def wait_ele(self, loc_or_ele, timeout=None):
"""返回用于等待子元素到达某个状态的等待器对象 """返回用于等待子元素到达某个状态的等待器对象
@ -755,7 +675,7 @@ class ChromiumElement(DrissionElement):
:param timeout: 等待超时时间 :param timeout: 等待超时时间
:return: 用于等待的ElementWaiter对象 :return: 用于等待的ElementWaiter对象
""" """
warn("方法即将弃用请用wait.ele_xxxx()方法代替。", DeprecationWarning) warn("wait_ele()方法即将弃用请用wait.ele_xxxx()方法代替。", DeprecationWarning)
return ChromiumElementWaiter(self, loc_or_ele, timeout) return ChromiumElementWaiter(self, loc_or_ele, timeout)
def click_at(self, offset_x=None, offset_y=None, button='left'): def click_at(self, offset_x=None, offset_y=None, button='left'):
@ -765,12 +685,12 @@ class ChromiumElement(DrissionElement):
:param button: 左键还是右键 :param button: 左键还是右键
:return: None :return: None
""" """
warn("方法即将弃用请用click.left_at()方法代替。", DeprecationWarning) warn("click_at()方法即将弃用请用click.left_at()方法代替。", DeprecationWarning)
self.click.left_at(offset_x, offset_y, button) self.click.left_at(offset_x, offset_y, button)
def r_click(self): def r_click(self):
"""右键单击""" """右键单击"""
warn("方法即将弃用请用click.right()方法代替。", DeprecationWarning) warn("r_click()方法即将弃用请用click.right()方法代替。", DeprecationWarning)
self.click.right() self.click.right()
def r_click_at(self, offset_x=None, offset_y=None): def r_click_at(self, offset_x=None, offset_y=None):
@ -779,14 +699,100 @@ class ChromiumElement(DrissionElement):
:param offset_y: 相对元素左上角坐标的y轴偏移量 :param offset_y: 相对元素左上角坐标的y轴偏移量
:return: None :return: None
""" """
warn("方法即将弃用请用click.right_at()方法代替。", DeprecationWarning) warn("r_click_at()方法即将弃用请用click.right_at()方法代替。", DeprecationWarning)
self.click.right_at(offset_x, offset_y) self.click.right_at(offset_x, offset_y)
def m_click(self): def m_click(self):
"""中键单击""" """中键单击"""
warn("方法即将弃用请用click.middle()方法代替。", DeprecationWarning) warn("m_click()方法即将弃用请用click.middle()方法代替。", DeprecationWarning)
self.click.middle() self.click.middle()
@property
def client_location(self):
"""返回元素左上角在视口中的坐标"""
warn("client_location属性即将弃用请用locations.viewport_location代替。", DeprecationWarning)
return self.locations.viewport_location
@property
def client_midpoint(self):
"""返回元素中间点在视口中的坐标"""
warn("client_midpoint属性即将弃用请用locations.client_midpoint代替。", DeprecationWarning)
return self.locations.viewport_midpoint
@property
def midpoint(self):
"""返回元素中间点的绝对坐标"""
warn("midpoint属性即将弃用请用locations.midpoint代替。", DeprecationWarning)
return self.locations.midpoint
def set_attr(self, attr, value):
"""设置元素attribute属性
:param attr: 属性名
:param value: 属性值
:return: None
"""
warn("set_attr()方法即将弃用请用set.attr()方法代替。", DeprecationWarning)
self.set.attr(attr, value)
def set_prop(self, prop, value):
"""设置元素property属性
:param prop: 属性名
:param value: 属性值
:return: None
"""
warn("set_prop()方法即将弃用请用set.prop()方法代替。", DeprecationWarning)
self.set.prop(prop, value)
def set_innerHTML(self, html):
"""设置元素innerHTML
:param html: html文本
:return: None
"""
warn("set_innerHTML()方法即将弃用请用set.innerHTML()方法代替。", DeprecationWarning)
self.set.innerHTML(html)
@property
def is_selected(self):
"""返回元素是否被选择"""
warn("is_selected属性即将弃用请用states.is_selected属性代替。", DeprecationWarning)
return self.states.is_selected
@property
def is_displayed(self):
"""返回元素是否显示"""
warn("is_displayed属性即将弃用请用states.is_displayed属性代替。", DeprecationWarning)
return self.states.is_displayed
@property
def is_enabled(self):
"""返回元素是否可用"""
warn("is_enabled属性即将弃用请用states.is_enabled属性代替。", DeprecationWarning)
return self.states.is_enabled
@property
def is_alive(self):
"""返回元素是否仍在DOM中"""
warn("is_alive属性即将弃用请用states.is_alive属性代替。", DeprecationWarning)
return self.states.is_alive
@property
def is_in_viewport(self):
"""返回元素是否出现在视口中,以元素可以接受点击的点为判断"""
warn("is_in_viewport属性即将弃用请用states.is_in_viewport属性代替。", DeprecationWarning)
return self.states.is_in_viewport
@property
def pseudo_before(self):
"""返回当前元素的::before伪元素内容"""
warn("pseudo_before属性即将弃用请用pseudo.before属性代替。", DeprecationWarning)
return self.pseudo.before
@property
def pseudo_after(self):
"""返回当前元素的::after伪元素内容"""
warn("pseudo_after属性即将弃用请用pseudo.after属性代替。", DeprecationWarning)
return self.pseudo.after
class ChromiumShadowRootElement(BaseElement): class ChromiumShadowRootElement(BaseElement):
"""ChromiumShadowRootElement是用于处理ShadowRoot的类使用方法和ChromiumElement基本一致""" """ChromiumShadowRootElement是用于处理ShadowRoot的类使用方法和ChromiumElement基本一致"""
@ -1258,7 +1264,7 @@ def run_js(page_or_ele, script, as_expr=False, timeout=None, args=None):
exceptionDetails = res.get('exceptionDetails') exceptionDetails = res.get('exceptionDetails')
if exceptionDetails: if exceptionDetails:
raise RuntimeError(f'javascript{script}\n错误信息: {exceptionDetails}') raise JavaScriptError(f'\njavascript运行错误\n{script}\n错误信息: \n{exceptionDetails}')
try: try:
return parse_js_result(page, page_or_ele, res.get('result')) return parse_js_result(page, page_or_ele, res.get('result'))
@ -1351,6 +1357,146 @@ def send_key(ele, modifier, key):
ele.page.run_cdp('Input.dispatchKeyEvent', **data) ele.page.run_cdp('Input.dispatchKeyEvent', **data)
class ChromiumElementStates(object):
def __init__(self, ele):
"""
:param ele: ChromiumElement
"""
self._ele = ele
@property
def is_selected(self):
"""返回元素是否被选择"""
return self._ele.run_js('return this.selected;')
@property
def is_displayed(self):
"""返回元素是否显示"""
return not (self._ele.style('visibility') == 'hidden'
or self._ele.run_js('return this.offsetParent === null;')
or self._ele.style('display') == 'none')
@property
def is_enabled(self):
"""返回元素是否可用"""
return not self._ele.run_js('return this.disabled;')
@property
def is_alive(self):
"""返回元素是否仍在DOM中"""
try:
d = self._ele.attrs
return True
except Exception:
return False
@property
def is_in_viewport(self):
"""返回元素是否出现在视口中,以元素可以接受点击的点为判断"""
x, y = self._ele.locations.click_point
return location_in_viewport(self._ele.page, x, y) if x else False
class ChromiumElementSetter(object):
def __init__(self, ele):
"""
:param ele: ChromiumElement
"""
self._ele = ele
def attr(self, attr, value):
"""设置元素attribute属性
:param attr: 属性名
:param value: 属性值
:return: None
"""
self._ele.page.run_cdp('DOM.setAttributeValue', nodeId=self._ele.node_id, name=attr, value=str(value))
def prop(self, prop, value):
"""设置元素property属性
:param prop: 属性名
:param value: 属性值
:return: None
"""
value = value.replace('"', r'\"')
self._ele.run_js(f'this.{prop}="{value}";')
def innerHTML(self, html):
"""设置元素innerHTML
:param html: html文本
:return: None
"""
self.prop('innerHTML', html)
class Locations(object):
def __init__(self, ele):
"""
:param ele: ChromiumElement
"""
self._ele = ele
@property
def page_location(self):
"""返回元素左上角的绝对坐标"""
cl = self.viewport_location
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
@property
def midpoint(self):
"""返回元素中间点的绝对坐标"""
cl = self.viewport_midpoint
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
@property
def viewport_location(self):
"""返回元素左上角在视口中的坐标"""
m = self._get_viewport_rect('border')
return (int(m[0]), int(m[1])) if m else (0, 0)
@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)) if m else (0, 0)
@property
def viewport_click_point(self):
"""返回元素左上角可接受点击的点视口坐标"""
m = self._get_viewport_rect('padding')
return (int(self.viewport_midpoint[0]), int(m[1]) + 1) if m else (0, 0)
@property
def click_point(self):
"""返回元素左上角可接受点击的点的绝对坐标"""
cl = self.viewport_click_point
return self._get_page_coord(cl[0], cl[1]) if cl else (0, 0)
@property
def screen_location(self):
"""返回元素在屏幕上坐标,左上角为(0, 0)"""
vx, vy = self._ele.page.rect.viewport_location
ex, ey = self.viewport_location
return vx + ex, ey + vy
def _get_viewport_rect(self, quad):
"""按照类型返回在可视窗口中的范围
:param quad: 方框类型margin border padding
:return: 四个角坐标大小为0时返回None
"""
try:
return self._ele.page.run_cdp('DOM.getBoxModel', nodeId=self._ele.node_id)['model'][quad]
except CallMethodError:
return None
def _get_page_coord(self, x, y):
"""根据绝对坐标获取窗口坐标"""
js = 'return document.documentElement.scrollLeft+" "+document.documentElement.scrollTop;'
xy = self._ele.run_js(js)
sx, sy = xy.split(' ')
return int(x + float(sx)), int(y + float(sy))
class Click(object): class Click(object):
def __init__(self, ele): def __init__(self, ele):
""" """
@ -1394,10 +1540,10 @@ class Click(object):
if not by_js: if not by_js:
self._ele.page.scroll.to_see(self._ele) self._ele.page.scroll.to_see(self._ele)
if self._ele.is_in_viewport: if self._ele.states.is_in_viewport:
client_x, client_y = self._ele._client_click_point client_x, client_y = self._ele.locations.viewport_click_point
if client_x: if client_x:
loc_x, loc_y = self._ele._click_point loc_x, loc_y = self._ele.locations.click_point
click = do_it(client_x, client_y, loc_x, loc_y) click = do_it(client_x, client_y, loc_x, loc_y)
if click: if click:
@ -1584,14 +1730,14 @@ class ChromiumSelect(object):
"""返回所有被选中的option元素列表 """返回所有被选中的option元素列表
:return: ChromiumElement对象组成的列表 :return: ChromiumElement对象组成的列表
""" """
return [x for x in self.options if x.is_selected] return [x for x in self.options if x.states.is_selected]
def clear(self): def clear(self):
"""清除所有已选项""" """清除所有已选项"""
if not self.is_multi: if not self.is_multi:
raise NotImplementedError("只能在多选菜单执行此操作。") raise NotImplementedError("只能在多选菜单执行此操作。")
for opt in self.options: for opt in self.options:
if opt.is_selected: if opt.states.is_selected:
opt.click(by_js=True) opt.click(by_js=True)
def by_text(self, text, timeout=None): def by_text(self, text, timeout=None):
@ -1782,7 +1928,7 @@ class ChromiumElementWaiter(object):
if isinstance(self.loc_or_ele, ChromiumElement): if isinstance(self.loc_or_ele, ChromiumElement):
end_time = perf_counter() + self.timeout end_time = perf_counter() + self.timeout
while perf_counter() < end_time: while perf_counter() < end_time:
if not self.loc_or_ele.is_alive: if not self.loc_or_ele.states.is_alive:
return True return True
ele = self.driver(self.loc_or_ele, timeout=.5) ele = self.driver(self.loc_or_ele, timeout=.5)
@ -1791,7 +1937,7 @@ class ChromiumElementWaiter(object):
end_time = perf_counter() + self.timeout end_time = perf_counter() + self.timeout
while perf_counter() < end_time: while perf_counter() < end_time:
if not ele.is_alive: if not ele.states.is_alive:
return True return True
return False return False
@ -1815,10 +1961,28 @@ class ChromiumElementWaiter(object):
end_time = perf_counter() + self.timeout end_time = perf_counter() + self.timeout
while perf_counter() < end_time: while perf_counter() < end_time:
if mode == 'display' and target.is_displayed: if mode == 'display' and target.states.is_displayed:
return True return True
elif mode == 'hidden' and not target.is_displayed: elif mode == 'hidden' and not target.states.is_displayed:
return True return True
return False return False
class Pseudo(object):
def __init__(self, ele):
"""
:param ele: ChromiumElement
"""
self._ele = ele
@property
def before(self):
"""返回当前元素的::before伪元素内容"""
return self._ele.style('content', 'before')
@property
def after(self):
"""返回当前元素的::after伪元素内容"""
return self._ele.style('content', 'after')

View File

@ -30,6 +30,10 @@ class ChromiumElement(DrissionElement):
self._click: Click = ... self._click: Click = ...
self._select: ChromiumSelect = ... self._select: ChromiumSelect = ...
self._wait: ChromiumWaiter = ... self._wait: ChromiumWaiter = ...
self._locations: Locations = ...
self._set: ChromiumElementSetter = ...
self._states: ChromiumElementStates = ...
self._pseudo: Pseudo = ...
def __repr__(self) -> str: ... def __repr__(self) -> str: ...
@ -71,15 +75,27 @@ class ChromiumElement(DrissionElement):
@property @property
def size(self) -> Tuple[int, int]: ... def size(self) -> Tuple[int, int]: ...
@property
def set(self) -> ChromiumElementSetter: ...
@property
def states(self) -> ChromiumElementStates: ...
@property
def location(self) -> Tuple[int, int]: ...
@property
def locations(self) -> Locations: ...
@property
def pseudo(self) -> Pseudo: ...
@property @property
def client_location(self) -> Tuple[int, int]: ... def client_location(self) -> Tuple[int, int]: ...
@property @property
def client_midpoint(self) -> Tuple[int, int]: ... def client_midpoint(self) -> Tuple[int, int]: ...
@property
def location(self) -> Tuple[int, int]: ...
@property @property
def midpoint(self) -> Tuple[int, int]: ... def midpoint(self) -> Tuple[int, int]: ...
@ -172,12 +188,12 @@ class ChromiumElement(DrissionElement):
def attr(self, attr: str) -> Union[str, None]: ... def attr(self, attr: str) -> Union[str, None]: ...
def set_attr(self, attr: str, value: str) -> None: ...
def remove_attr(self, attr: str) -> None: ... def remove_attr(self, attr: str) -> None: ...
def prop(self, prop: str) -> Union[str, int, None]: ... def prop(self, prop: str) -> Union[str, int, None]: ...
def set_attr(self, attr: str, value: str) -> None: ...
def set_prop(self, prop: str, value: str) -> None: ... def set_prop(self, prop: str, value: str) -> None: ...
def set_innerHTML(self, html: str) -> None: ... def set_innerHTML(self, html: str) -> None: ...
@ -243,9 +259,25 @@ class ChromiumElement(DrissionElement):
def _get_ele_path(self, mode: str) -> str: ... def _get_ele_path(self, mode: str) -> str: ...
def _get_client_rect(self, quad: str) -> Union[list, None]: ...
def _get_absolute_rect(self, x: int, y: int) -> Tuple[int, int]: ... class ChromiumElementStates(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
@property
def is_selected(self) -> bool: ...
@property
def is_displayed(self) -> bool: ...
@property
def is_enabled(self) -> bool: ...
@property
def is_alive(self) -> bool: ...
@property
def is_in_viewport(self) -> bool: ...
class ChromiumShadowRootElement(BaseElement): class ChromiumShadowRootElement(BaseElement):
@ -384,6 +416,47 @@ def send_enter(ele: ChromiumElement) -> None: ...
def send_key(ele: ChromiumElement, modifier: int, key: str) -> None: ... def send_key(ele: ChromiumElement, modifier: int, key: str) -> None: ...
class ChromiumElementSetter(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
def attr(self, attr: str, value: str) -> None: ...
def prop(self, prop: str, value: str) -> None: ...
def innerHTML(self, html: str) -> None: ...
class Locations(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
@property
def page_location(self) -> Tuple[int, int]: ...
@property
def viewport_location(self) -> Tuple[int, int]: ...
@property
def viewport_midpoint(self) -> Tuple[int, int]: ...
@property
def midpoint(self) -> Tuple[int, int]: ...
@property
def viewport_click_point(self) -> Tuple[int, int]: ...
@property
def click_point(self) -> Tuple[int, int]: ...
@property
def screen_location(self) -> Tuple[int, int]: ...
def _get_viewport_rect(self, quad: str) -> Union[list, None]: ...
def _get_page_coord(self, x: int, y: int) -> Tuple[int, int]: ...
class Click(object): class Click(object):
def __init__(self, ele: ChromiumElement): def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ... self._ele: ChromiumElement = ...
@ -511,3 +584,14 @@ class ChromiumElementWaiter(object):
def hidden(self) -> bool: ... def hidden(self) -> bool: ...
def _wait_ele(self, mode: str) -> Union[None, bool]: ... def _wait_ele(self, mode: str) -> Union[None, bool]: ...
class Pseudo(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
@property
def before(self) -> str: ...
@property
def after(self) -> str: ...

View File

@ -233,7 +233,7 @@ class ChromiumFrame(ChromiumBase):
def is_displayed(self): def is_displayed(self):
"""返回frame元素是否显示""" """返回frame元素是否显示"""
self._check_ok() self._check_ok()
return self.frame_ele.is_displayed return self.frame_ele.states.is_displayed
@property @property
def xpath(self): def xpath(self):
@ -459,7 +459,7 @@ class ChromiumFrame(ChromiumBase):
:param value: 属性值 :param value: 属性值
:return: None :return: None
""" """
warn("方法即将弃用请用set.attr()方法代替。", DeprecationWarning) warn("set_attr()方法即将弃用请用set.attr()方法代替。", DeprecationWarning)
self.set.attr(attr, value) self.set.attr(attr, value)
@ -494,4 +494,4 @@ class ChromiumFrameSetter(ChromiumBaseSetter):
:return: None :return: None
""" """
self._page._check_ok() self._page._check_ok()
self._page.frame_ele.set_attr(attr, value) self._page.frame_ele.set.attr(attr, value)

View File

@ -92,6 +92,7 @@ class ChromiumPage(ChromiumBase):
"""添加ChromiumPage独有的运行配置""" """添加ChromiumPage独有的运行配置"""
super()._chromium_init() super()._chromium_init()
self._alert = Alert() self._alert = Alert()
self._rect = None
def _driver_init(self, tab_id): def _driver_init(self, tab_id):
"""新建页面、页面刷新、切换标签页后要进行的cdp参数初始化 """新建页面、页面刷新、切换标签页后要进行的cdp参数初始化
@ -172,6 +173,12 @@ class ChromiumPage(ChromiumBase):
"""返回下载器对象""" """返回下载器对象"""
return self.download_set._switched_DownloadKit return self.download_set._switched_DownloadKit
@property
def rect(self):
if self._rect is None:
self._rect = ChromiumTabRect(self)
return self._rect
def get_tab(self, tab_id=None): def get_tab(self, tab_id=None):
"""获取一个标签页对象 """获取一个标签页对象
:param tab_id: 要获取的标签页id为None时获取当前tab :param tab_id: 要获取的标签页id为None时获取当前tab
@ -356,16 +363,82 @@ class ChromiumPage(ChromiumBase):
:param tab_id: 标签页id不传入则设置当前tab :param tab_id: 标签页id不传入则设置当前tab
:return: None :return: None
""" """
warn("方法即将弃用请用set.main_tab()方法代替。", DeprecationWarning) warn("set_main_tab()方法即将弃用请用set.main_tab()方法代替。", DeprecationWarning)
self.set.main_tab(tab_id) self.set.main_tab(tab_id)
@property @property
def set_window(self): def set_window(self):
"""返回用于设置窗口大小的对象""" """返回用于设置窗口大小的对象"""
warn("方法即将弃用请用set.window.xxxx()方法代替。", DeprecationWarning) warn("set_window()方法即将弃用请用set.window.xxxx()方法代替。", DeprecationWarning)
return WindowSetter(self) return WindowSetter(self)
class ChromiumTabRect(object):
def __init__(self, page):
self._page = page
@property
def browser_location(self):
"""返回浏览器在屏幕上的坐标"""
r = self._get_browser_rect()
if r['windowState'] in ('maximized', 'fullscreen'):
return 0, 0
return r['left'] + 7, r['top']
@property
def page_location(self):
"""返回页面左上角在屏幕中坐标,左上角为(0, 0)"""
w, h = self.viewport_location
r = self._get_page_rect()['layoutViewport']
return w - r['pageX'], h - r['pageY']
@property
def viewport_location(self):
"""返回视口在屏幕中坐标,左上角为(0, 0)"""
w_bl, h_bl = self.browser_location
w_bs, h_bs = self.browser_size
w_vs, h_vs = self.viewport_size_with_scrollbar
return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs
@property
def browser_size(self):
"""返回浏览器大小"""
r = self._get_browser_rect()
if r['windowState'] == 'fullscreen':
return r['width'], r['height']
elif r['windowState'] == 'maximized':
return r['width'] - 16, r['height'] - 16
else:
return r['width'] - 16, r['height'] - 7
@property
def page_size(self):
"""返回页面总宽高,格式:(宽, 高)"""
r = self._get_page_rect()['contentSize']
return r['width'], r['height']
@property
def viewport_size(self):
"""返回视口宽高,不包括滚动条,格式:(宽, 高)"""
r = self._get_page_rect()['visualViewport']
return r['clientWidth'], r['clientHeight']
@property
def viewport_size_with_scrollbar(self):
"""返回视口宽高,包括滚动条,格式:(宽, 高)"""
r = self._page.run_js('return window.innerWidth.toString() + " " + window.innerHeight.toString();')
w, h = r.split(' ')
return int(w), int(h)
def _get_page_rect(self):
"""获取页面范围信息"""
return self._page.run_cdp_loaded('Page.getLayoutMetrics')
def _get_browser_rect(self):
"""获取浏览器范围信息"""
return self._page.browser_driver.Browser.getWindowForTarget(targetId=self._page.tab_id)['bounds']
class ChromiumDownloadSetter(DownloadSetter): class ChromiumDownloadSetter(DownloadSetter):
"""用于设置下载参数的类""" """用于设置下载参数的类"""
@ -536,8 +609,8 @@ class WindowSetter(object):
if s != 'normal': if s != 'normal':
self._perform({'windowState': 'normal'}) self._perform({'windowState': 'normal'})
info = self._get_info()['bounds'] info = self._get_info()['bounds']
width = width or info['width'] width = width - 16 if width else info['width']
height = height or info['height'] height = height + 7 if height else info['height']
self._perform({'width': width, 'height': height}) self._perform({'width': width, 'height': height})
def location(self, x=None, y=None): def location(self, x=None, y=None):
@ -551,7 +624,7 @@ class WindowSetter(object):
info = self._get_info()['bounds'] info = self._get_info()['bounds']
x = x if x is not None else info['left'] x = x if x is not None else info['left']
y = y if y is not None else info['top'] y = y if y is not None else info['top']
self._perform({'left': x, 'top': y}) self._perform({'left': x - 8, 'top': y})
def _get_info(self): def _get_info(self):
"""获取窗口位置及大小信息""" """获取窗口位置及大小信息"""
@ -574,7 +647,7 @@ class ChromiumPageSetter(ChromiumBaseSetter):
self._page._main_tab = tab_id or self._page.tab_id self._page._main_tab = tab_id or self._page.tab_id
@property @property
def windows(self): def window(self):
"""返回用于设置浏览器窗口的对象""" """返回用于设置浏览器窗口的对象"""
return WindowSetter(self._page) return WindowSetter(self._page)

View File

@ -33,6 +33,7 @@ class ChromiumPage(ChromiumBase):
self._download_path: str = ... self._download_path: str = ...
self._download_set: ChromiumDownloadSetter = ... self._download_set: ChromiumDownloadSetter = ...
self._browser_driver: ChromiumDriver = ... self._browser_driver: ChromiumDriver = ...
self._rect: ChromiumTabRect = ...
def _connect_browser(self, def _connect_browser(self,
addr_driver_opts: Union[str, ChromiumDriver, DriverOptions] = None, addr_driver_opts: Union[str, ChromiumDriver, DriverOptions] = None,
@ -51,6 +52,9 @@ class ChromiumPage(ChromiumBase):
@property @property
def tabs(self) -> List[str]: ... def tabs(self) -> List[str]: ...
@property
def rect(self) -> ChromiumTabRect: ...
@property @property
def main_tab(self) -> str: ... def main_tab(self) -> str: ...
@ -108,6 +112,36 @@ class ChromiumPage(ChromiumBase):
def _on_alert_open(self, **kwargs): ... def _on_alert_open(self, **kwargs): ...
class ChromiumTabRect(object):
def __init__(self, page: ChromiumPage):
self._page: ChromiumPage = ...
@property
def browser_location(self) -> Tuple[int, int]: ...
@property
def page_location(self) -> Tuple[int, int]: ...
@property
def viewport_location(self) -> Tuple[int, int]: ...
@property
def browser_size(self) -> Tuple[int, int]: ...
@property
def page_size(self) -> Tuple[int, int]: ...
@property
def viewport_size(self) -> Tuple[int, int]: ...
@property
def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ...
def _get_page_rect(self) -> dict: ...
def _get_browser_rect(self) -> dict: ...
class ChromiumDownloadSetter(DownloadSetter): class ChromiumDownloadSetter(DownloadSetter):
def __init__(self, page: ChromiumPage): def __init__(self, page: ChromiumPage):
self._page: ChromiumPage = ... self._page: ChromiumPage = ...
@ -189,4 +223,4 @@ class ChromiumPageSetter(ChromiumBaseSetter):
def main_tab(self, tab_id: str = None) -> None: ... def main_tab(self, tab_id: str = None) -> None: ...
@property @property
def windows(self) -> WindowSetter: ... def window(self) -> WindowSetter: ...

View File

@ -11,7 +11,7 @@ from time import perf_counter, sleep
from requests import get as requests_get from requests import get as requests_get
from DrissionPage.configs.driver_options import DriverOptions from DrissionPage.configs.chromium_options import ChromiumOptions
from .tools import port_is_using, get_exe_from_port from .tools import port_is_using, get_exe_from_port
@ -65,7 +65,7 @@ def get_launch_args(opt):
result = list(result) result = list(result)
# ----------处理插件extensions------------- # ----------处理插件extensions-------------
ext = opt._extension_files if isinstance(opt, DriverOptions) else opt.extensions ext = opt.extensions if isinstance(opt, ChromiumOptions) else opt._extension_files
if ext: if ext:
ext = ','.join(set(ext)) ext = ','.join(set(ext))
ext = f'--load-extension={ext}' ext = f'--load-extension={ext}'
@ -79,12 +79,12 @@ def set_prefs(opt):
:param opt: DriverOptions或ChromiumOptions :param opt: DriverOptions或ChromiumOptions
:return: None :return: None
""" """
if isinstance(opt, DriverOptions): if isinstance(opt, ChromiumOptions):
prefs = opt.experimental_options.get('prefs', None)
del_list = []
else:
prefs = opt.preferences prefs = opt.preferences
del_list = opt._prefs_to_del del_list = opt._prefs_to_del
else:
prefs = opt.experimental_options.get('prefs', None)
del_list = []
if not opt.user_data_path: if not opt.user_data_path:
return return

View File

@ -34,3 +34,7 @@ class TabClosedError(BaseError):
class NotElementFoundError(BaseError): class NotElementFoundError(BaseError):
_info = '没有找到元素。' _info = '没有找到元素。'
class JavaScriptError(BaseError):
_info = 'JavaScript运行错误。'

View File

@ -1,11 +1,11 @@
[paths] [paths]
chromedriver_path = D:\python\projects\DrissionPage\DrissionPage\chromedriver.exe chromedriver_path =
download_path = download_path =
[chrome_options] [chrome_options]
debugger_address = 127.0.0.1:9222 debugger_address = 127.0.0.1:9222
binary_location = D:\python\Chrome109\chrome.exe binary_location = chrome
arguments = ['--no-first-run', '--disable-gpu', '--ignore-certificate-errors', '--disable-infobars', '--disable-popup-blocking', '--user-data-dir=D:\\python\\Chrome109\\user_data'] arguments = ['--no-first-run', '--disable-gpu', '--ignore-certificate-errors', '--disable-infobars', '--disable-popup-blocking']
extensions = [] extensions = []
experimental_options = {'prefs': {'profile.default_content_settings.popups': 0, 'profile.default_content_setting_values': {'notifications': 2}, 'plugins.plugins_list': [{'enabled': False, 'name': 'Chrome PDF Viewer'}]}, 'useAutomationExtension': False, 'excludeSwitches': ['enable-automation']} experimental_options = {'prefs': {'profile.default_content_settings.popups': 0, 'profile.default_content_setting_values': {'notifications': 2}, 'plugins.plugins_list': [{'enabled': False, 'name': 'Chrome PDF Viewer'}]}, 'useAutomationExtension': False, 'excludeSwitches': ['enable-automation']}
page_load_strategy = normal page_load_strategy = normal

View File

@ -36,6 +36,8 @@ class MixPage(SessionPage, DriverPage, BasePage):
self._wait_object = None self._wait_object = None
self._response = None self._response = None
self._scroll = None self._scroll = None
self._download_set = None
self._download_path = None
if self._mode == 'd': if self._mode == 'd':
try: try:

View File

@ -334,7 +334,7 @@ class SessionPage(BasePage):
:param cookies: cookies信息 :param cookies: cookies信息
:return: None :return: None
""" """
warn("此方法即将弃用请用set.load_strategy.xxxx()方法代替。", DeprecationWarning) warn("set_cookies()方法即将弃用请用set.cookies()方法代替。", DeprecationWarning)
self.set.cookies(cookies) self.set.cookies(cookies)
def set_headers(self, headers): def set_headers(self, headers):
@ -342,12 +342,12 @@ class SessionPage(BasePage):
:param headers: dict形式的headers :param headers: dict形式的headers
:return: None :return: None
""" """
warn("此方法即将弃用请用set.load_strategy.xxxx()方法代替。", DeprecationWarning) warn("set_headers()方法即将弃用请用set.headers()方法代替。", DeprecationWarning)
self.set.headers(headers) self.set.headers(headers)
def set_user_agent(self, ua): def set_user_agent(self, ua):
"""设置user agent""" """设置user agent"""
warn("此方法即将弃用请用set.load_strategy.xxxx()方法代替。", DeprecationWarning) warn("set_user_agent()方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning)
self.set.user_agent(ua) self.set.user_agent(ua)

View File

@ -445,7 +445,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:return: None :return: None
""" """
# 添加cookie到driver # 添加cookie到driver
warn("方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning) warn("set_cookies()方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning)
self.set.cookies(cookies, set_session, set_driver) self.set.cookies(cookies, set_session, set_driver)
def set_headers(self, headers) -> None: def set_headers(self, headers) -> None:
@ -453,12 +453,12 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:param headers: dict格式的headers数据 :param headers: dict格式的headers数据
:return: None :return: None
""" """
warn("方法即将弃用请用set.headers()方法代替。", DeprecationWarning) warn("set_headers()方法即将弃用请用set.headers()方法代替。", DeprecationWarning)
self.set.headers(headers) self.set.headers(headers)
def set_user_agent(self, ua, platform=None): def set_user_agent(self, ua, platform=None):
"""设置user agentd模式下只有当前tab有效""" """设置user agentd模式下只有当前tab有效"""
warn("方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning) warn("set_user_agent()方法即将弃用请用set.user_agent()方法代替。", DeprecationWarning)
self.set.user_agent(ua, platform) self.set.user_agent(ua, platform)