不少修改(+)

修复一个cookies问题;
元素被覆盖时states.is_covered返回覆盖元素id;
click()by_js默认改为False;
修复html带xml描述时SessionPage报错问题;
get()逻辑避免浏览器自动重试;
删除set.cookie();
增加set.cookies.clear()和set.cookies.remove();
set.cookies()可接收单个cookie;
修复select问题;
ChromiumDriver改为Driver
This commit is contained in:
g1879 2023-12-17 19:16:41 +08:00
parent 35c25fa454
commit 05cac3b69a
25 changed files with 221 additions and 142 deletions

View File

@ -5,7 +5,7 @@
"""
from time import sleep, perf_counter
from .chromium_driver import BrowserDriver, ChromiumDriver
from .driver import BrowserDriver, Driver
from .._functions.tools import stop_process_on_port, raise_error
from .._units.downloader import DownloadManager
@ -42,7 +42,7 @@ class Browser(object):
self.id = browser_id
self._frames = {}
self._drivers = {}
# self._drivers = {t: ChromiumDriver(t, 'page', address) for t in self.tabs}
# self._drivers = {t: Driver(t, 'page', address) for t in self.tabs}
self._connected = False
self._process_id = None
@ -57,16 +57,16 @@ class Browser(object):
self._driver.set_callback('Target.targetCreated', self._onTargetCreated)
def _get_driver(self, tab_id):
"""获取对应tab id的ChromiumDriver
"""获取对应tab id的Driver
:param tab_id: 标签页id
:return: ChromiumDriver对象
:return: Driver对象
"""
return self._drivers.pop(tab_id, ChromiumDriver(tab_id, 'page', self.address))
return self._drivers.pop(tab_id, Driver(tab_id, 'page', self.address))
def _onTargetCreated(self, **kwargs):
"""标签页创建时执行"""
if kwargs['targetInfo']['type'] == 'page' and not kwargs['targetInfo']['url'].startswith('devtools://'):
self._drivers[kwargs['targetInfo']['targetId']] = ChromiumDriver(kwargs['targetInfo']['targetId'], 'page',
self._drivers[kwargs['targetInfo']['targetId']] = Driver(kwargs['targetInfo']['targetId'], 'page',
self.address)
def _onTargetDestroyed(self, **kwargs):

View File

@ -5,7 +5,7 @@
"""
from typing import List, Optional, Union
from .chromium_driver import BrowserDriver, ChromiumDriver
from .driver import BrowserDriver, Driver
from .._pages.chromium_page import ChromiumPage
from .._units.downloader import DownloadManager
@ -26,7 +26,7 @@ class Browser(object):
def __init__(self, address: str, browser_id: str, page: ChromiumPage): ...
def _get_driver(self, tab_id: str) -> ChromiumDriver: ...
def _get_driver(self, tab_id: str) -> Driver: ...
def run_cdp(self, cmd, **cmd_args) -> dict: ...

View File

@ -12,7 +12,7 @@ from requests import get
from websocket import WebSocketTimeoutException, WebSocketConnectionClosedException, create_connection
class ChromiumDriver(object):
class Driver(object):
def __init__(self, tab_id, tab_type, address):
"""
:param tab_id: 标签页id
@ -211,12 +211,12 @@ class ChromiumDriver(object):
self.event_handlers.pop(event, None)
def __str__(self):
return f"<ChromiumDriver {self.id}>"
return f"<Driver {self.id}>"
__repr__ = __str__
class BrowserDriver(ChromiumDriver):
class BrowserDriver(Driver):
BROWSERS = {}
def __new__(cls, tab_id, tab_type, address, browser):

View File

@ -14,14 +14,14 @@ from .browser import Browser
class GenericAttr(object):
def __init__(self, name: str, tab: ChromiumDriver): ...
def __init__(self, name: str, tab: Driver): ...
def __getattr__(self, item: str) -> Callable: ...
def __setattr__(self, key: str, value: Callable) -> None: ...
class ChromiumDriver(object):
class Driver(object):
id: str
address: str
type: str
@ -58,8 +58,8 @@ class ChromiumDriver(object):
def __str__(self) -> str: ...
class BrowserDriver(ChromiumDriver):
BROWSERS: Dict[str, ChromiumDriver] = ...
class BrowserDriver(Driver):
BROWSERS: Dict[str, Driver] = ...
browser: Browser = ...
def __new__(cls, tab_id: str, tab_type: str, address: str, browser: Browser): ...

View File

@ -26,12 +26,12 @@ PIC_TYPE = Literal['jpg', 'jpeg', 'png', 'webp', True]
class ChromiumElement(DrissionElement):
def __init__(self, page: ChromiumBase, node_id: str = None, obj_id: str = None, backend_id: str = None):
def __init__(self, page: ChromiumBase, node_id: str = None, obj_id: str = None, backend_id: int = None):
self._tag: str = ...
self.page: Union[ChromiumPage, WebPage] = ...
self._node_id: str = ...
self._obj_id: str = ...
self._backend_id: str = ...
self._backend_id: int = ...
self._doc_id: str = ...
self._scroll: ElementScroller = ...
self._clicker: Clicker = ...
@ -196,9 +196,9 @@ class ChromiumElement(DrissionElement):
def drag_to(self, ele_or_loc: Union[tuple, ChromiumElement], duration: float = 0.5) -> None: ...
def _get_obj_id(self, node_id: str = None, backend_id: str = None) -> str: ...
def _get_obj_id(self, node_id: str = None, backend_id: int = None) -> str: ...
def _get_node_id(self, obj_id: str = None, backend_id: str = None) -> str: ...
def _get_node_id(self, obj_id: str = None, backend_id: int = None) -> str: ...
def _get_backend_id(self, node_id: str) -> str: ...
@ -207,10 +207,10 @@ class ChromiumElement(DrissionElement):
class ShadowRoot(BaseElement):
def __init__(self, parent_ele: ChromiumElement, obj_id: str = None, backend_id: str = None):
def __init__(self, parent_ele: ChromiumElement, obj_id: str = None, backend_id: int = None):
self._obj_id: str = ...
self._node_id: str = ...
self._backend_id: str = ...
self._backend_id: int = ...
self.page: ChromiumPage = ...
self.parent_ele: ChromiumElement = ...
self._states: ShadowRootStates = ...
@ -277,7 +277,7 @@ class ShadowRoot(BaseElement):
def _get_obj_id(self, back_id: str) -> str: ...
def _get_backend_id(self, node_id: str) -> str: ...
def _get_backend_id(self, node_id: str) -> int: ...
def find_in_chromium_ele(ele: ChromiumElement, loc: Union[str, Tuple[str, str]],

View File

@ -4,7 +4,7 @@
@Contact : g1879@qq.com
"""
from html import unescape
from re import match, DOTALL
from re import match, sub, DOTALL
from lxml.etree import tostring
from lxml.html import HtmlElement, fromstring
@ -342,15 +342,18 @@ def make_session_ele(html_or_ele, loc=None, single=True):
# 各种页面对象
elif isinstance(html_or_ele, BasePage):
page = html_or_ele
html_or_ele = fromstring(html_or_ele.html)
html = html_or_ele.html
if html.startswith('<?xml '):
html = sub(r'^<\?xml.*?>', '', html)
html_or_ele = fromstring(html)
# 直接传入html文本
elif isinstance(html_or_ele, str):
page = None
html_or_ele = fromstring(html_or_ele)
# ShadowRoot, ChromiumFrame
elif isinstance(html_or_ele, BaseElement) or the_type.endswith(".ChromiumFrame'>"):
# ShadowRoot
elif isinstance(html_or_ele, BaseElement):
page = html_or_ele.page
html_or_ele = fromstring(html_or_ele.html)

View File

@ -251,20 +251,25 @@ def set_browser_cookies(page, cookies):
cookie['expires'] = int(cookie['expiry'])
cookie.pop('expiry')
if 'expires' in cookie and isinstance(cookie['expires'], str):
if cookie['expires'].isdigit():
cookie['expires'] = int(cookie['expires'])
if 'expires' in cookie:
if not cookie['expires']:
cookie.pop('expires')
elif cookie['expires'].replace('.', '').isdigit():
cookie['expires'] = float(cookie['expires'])
elif isinstance(cookie['expires'], str):
if cookie['expires'].isdigit():
cookie['expires'] = int(cookie['expires'])
elif cookie['expires'].replace('.', '').isdigit():
cookie['expires'] = float(cookie['expires'])
else:
try:
cookie['expires'] = datetime.strptime(cookie['expires'],
'%a, %d %b %Y %H:%M:%S GMT').timestamp()
except ValueError:
cookie['expires'] = datetime.strptime(cookie['expires'],
'%a, %d %b %y %H:%M:%S GMT').timestamp()
else:
try:
cookie['expires'] = datetime.strptime(cookie['expires'],
'%a, %d %b %Y %H:%M:%S GMT').timestamp()
except ValueError:
cookie['expires'] = datetime.strptime(cookie['expires'],
'%a, %d %b %y %H:%M:%S GMT').timestamp()
if cookie['value'] is None:
cookie['value'] = ''
elif not isinstance(cookie['value'], str):

View File

@ -156,31 +156,31 @@ class ChromiumBase(BasePage):
timeout = timeout if timeout >= .5 else .5
self._is_reading = True
end_time = perf_counter() + timeout
try:
b_id = self.run_cdp('DOM.getDocument', _timeout=timeout)['root']['backendNodeId']
timeout = end_time - perf_counter()
timeout = .5 if timeout < 0 else timeout
self._root_id = self.run_cdp('DOM.resolveNode', backendNodeId=b_id, _timeout=timeout)['object']['objectId']
while perf_counter() < end_time:
try:
b_id = self.run_cdp('DOM.getDocument', _timeout=timeout)['root']['backendNodeId']
timeout = end_time - perf_counter()
timeout = .5 if timeout < 0 else timeout
self._root_id = self.run_cdp('DOM.resolveNode',
backendNodeId=b_id, _timeout=timeout)['object']['objectId']
r = self.run_cdp('Page.getFrameTree')
for i in findall(r"'id': '(.*?)'", str(r)):
self.browser._frames[i] = self.tab_id
if self._debug:
print('获取文档结束')
result = True
break
r = self.run_cdp('Page.getFrameTree')
for i in findall(r"'id': '(.*?)'", str(r)):
self.browser._frames[i] = self.tab_id
if self._debug:
print('获取文档结束')
return True
except:
timeout = end_time - perf_counter()
timeout = .5 if timeout < 0 else timeout
except:
if self._debug:
print('获取文档失败。')
from traceback import print_exc
print_exc()
print('请把报错信息和重现方法告知作者,感谢。\nhttps://gitee.com/g1879/DrissionPage/issues/new')
raise
# return False
else:
result = False
finally:
self._is_loading = False
self._is_reading = False
self._is_loading = False
self._is_reading = False
return result
def _onFrameDetached(self, **kwargs):
self.browser._frames.pop(kwargs['frameId'], None)
@ -230,8 +230,8 @@ class ChromiumBase(BasePage):
if self._load_mode == 'eager':
self.run_cdp('Page.stopLoading')
self._get_document(self._load_end_time - perf_counter() - .1)
self._doc_got = True
if self._get_document(self._load_end_time - perf_counter() - .1):
self._doc_got = True
self._ready_state = 'interactive'
if self._debug:
@ -243,8 +243,7 @@ class ChromiumBase(BasePage):
print(f'{self._frame_id}触发LoadEventFired')
print('在LoadEventFired变成complete')
if self._doc_got is False:
self._get_document(self._load_end_time - perf_counter() - .1)
if self._doc_got is False and self._get_document(self._load_end_time - perf_counter() - .1):
self._doc_got = True
self._ready_state = 'complete'
@ -369,7 +368,7 @@ class ChromiumBase(BasePage):
@property
def driver(self):
"""返回用于控制浏览器的ChromiumDriver对象"""
"""返回用于控制浏览器的Driver对象"""
if self._driver is None:
raise RuntimeError('浏览器已关闭或链接已断开。')
return self._driver
@ -960,6 +959,9 @@ class ChromiumBase(BasePage):
sleep(interval)
if self._debug or show_errmsg:
print(f'重试{t + 1} {to_url}')
end_time1 = end_time - perf_counter()
while self._ready_state not in ('loading', 'complete') and perf_counter() < end_time1: # 等待出错信息显示
sleep(.1)
self.stop_loading()
continue

View File

@ -8,7 +8,7 @@ from typing import Union, Tuple, List, Any, Optional, Literal
from .._base.base import BasePage
from .._base.browser import Browser
from .._base.chromium_driver import ChromiumDriver
from .._base.driver import Driver
from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement
@ -34,7 +34,7 @@ class ChromiumBase(BasePage):
self._browser: Browser = ...
self._page: ChromiumPage = ...
self.address: str = ...
self._driver: ChromiumDriver = ...
self._driver: Driver = ...
self._frame_id: str = ...
self._is_reading: bool = ...
self._is_timeout: bool = ...
@ -103,7 +103,7 @@ class ChromiumBase(BasePage):
def title(self) -> str: ...
@property
def driver(self) -> ChromiumDriver: ...
def driver(self) -> Driver: ...
@property
def url(self) -> str: ...

View File

@ -27,7 +27,7 @@ class ChromiumFrame(ChromiumBase):
self.tab: ChromiumTab = ...
self._tab_id: str = ...
self._frame_ele: ChromiumElement = ...
self._backend_id: str = ...
self._backend_id: int = ...
self._doc_ele: ChromiumElement = ...
self._is_diff_domain: bool = ...
self.doc_ele: ChromiumElement = ...

View File

@ -37,7 +37,7 @@ class ChromiumPage(ChromiumBase):
def _handle_options(self, addr_or_opts):
"""设置浏览器启动属性
:param addr_or_opts: 'ip:port'ChromiumOptionsChromiumDriver
:param addr_or_opts: 'ip:port'ChromiumOptionsDriver
:return: 返回浏览器地址
"""
if not addr_or_opts:

View File

@ -19,7 +19,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""初始化函数
:param mode: 'd' 's'即driver模式和session模式
:param timeout: 超时时间d模式时为寻找元素时间s模式时为连接时间默认10秒
:param chromium_options: ChromiumDriver对象只使用s模式时应传入False
:param chromium_options: Driver对象只使用s模式时应传入False
:param session_or_options: Session对象或SessionOptions对象只使用d模式时应传入False
"""
chromium_options = chromium_options or driver_or_options

View File

@ -12,7 +12,7 @@ from .chromium_page import ChromiumPage
from .chromium_tab import WebPageTab
from .session_page import SessionPage
from .._base.base import BasePage
from .._base.chromium_driver import ChromiumDriver
from .._base.driver import Driver
from .._configs.chromium_options import ChromiumOptions
from .._configs.session_options import SessionOptions
from .._elements.chromium_element import ChromiumElement
@ -162,9 +162,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
-> Union[ChromiumElement, SessionElement, ChromiumFrame, str, None, List[Union[SessionElement, str]], List[
Union[ChromiumElement, str, ChromiumFrame]]]: ...
def _set_start_options(self, dr_opt: Union[ChromiumDriver, bool, None],
def _set_start_options(self, dr_opt: Union[Driver, bool, None],
se_opt: Union[Session, SessionOptions, bool, None]) -> None: ...
def quit(self, timeout: float = 5, force: bool = True) -> None: ...
def _on_download_begin(self, **kwargs): ...

View File

@ -5,7 +5,7 @@
"""
from typing import Union, Tuple, Any, Literal
from .._base.chromium_driver import ChromiumDriver
from .._base.driver import Driver
from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase
@ -43,7 +43,7 @@ class Actions:
def __init__(self, page: ChromiumBase):
self.page: ChromiumBase = ...
self._dr: ChromiumDriver = ...
self._dr: Driver = ...
self.modifier: int = ...
self.curr_x: int = ...
self.curr_y: int = ...

View File

@ -17,7 +17,7 @@ class Clicker(object):
"""
self._ele = ele
def __call__(self, by_js=None, timeout=1.5, wait_stop=True):
def __call__(self, by_js=False, timeout=1.5, wait_stop=True):
"""点击元素
如果遇到遮挡可选择是否用js点击
:param by_js: 是否用js点击为None时先用模拟点击遇到遮挡改用js为True时直接用js点击为False时只用模拟点击
@ -27,7 +27,7 @@ class Clicker(object):
"""
return self.left(by_js, timeout, wait_stop)
def left(self, by_js=None, timeout=1.5, wait_stop=True):
def left(self, by_js=False, timeout=1.5, wait_stop=True):
"""点击元素可选择是否用js点击
:param by_js: 是否用js点击为None时先用模拟点击遇到遮挡改用js为True时直接用js点击为False时只用模拟点击
:param timeout: 模拟点击的超时时间等待元素可见可用进入视口

View File

@ -3,7 +3,7 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Union
from typing import Union, Optional
from .._elements.chromium_element import ChromiumElement
@ -12,9 +12,9 @@ class Clicker(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
def __call__(self, by_js: Union[None, bool] = None, timeout: float = 1.5, wait_stop: bool = True) -> bool: ...
def __call__(self, by_js: Optional[bool] = False, timeout: float = 1.5, wait_stop: bool = True) -> bool: ...
def left(self, by_js: Union[None, bool] = None, timeout: float = 1.5, wait_stop: bool = True) -> bool: ...
def left(self, by_js: Optional[bool] = False, timeout: float = 1.5, wait_stop: bool = True) -> bool: ...
def right(self) -> None: ...

View File

@ -0,0 +1,64 @@
# -*- coding:utf-8 -*-
from http.cookiejar import Cookie
from .._functions.web import set_browser_cookies, set_session_cookies
class CookiesSetter(object):
def __init__(self, page):
self._page = page
def __call__(self, cookies):
"""设置一个或多个cookie
:param cookies: cookies信息
:return: None
"""
if (isinstance(cookies, dict) and 'name' in cookies and 'value' in cookies) or isinstance(cookies, Cookie):
cookies = [cookies]
set_browser_cookies(self._page, cookies)
def remove(self, name, url=None, domain=None, path=None):
"""删除一个cookie
:param name: cookie的name字段
:param url: cookie的url字段可选
:param domain: cookie的domain字段可选
:param path: cookie的path字段可选
:return: None
"""
d = {'name': name}
if url is not None:
d['url'] = url
if domain is not None:
d['domain'] = domain
if path is not None:
d['path'] = path
self._page.run_cdp('Network.deleteCookies', **d)
def clear(self):
"""清除cookies"""
self._page.run_cdp('Network.clearBrowserCookies')
class SessionCookiesSetter(object):
def __init__(self, page):
self._page = page
def __call__(self, cookies):
"""设置多个cookie注意不要传入单个
:param cookies: cookies信息
:return: None
"""
if (isinstance(cookies, dict) and 'name' in cookies and 'value' in cookies) or isinstance(cookies, Cookie):
cookies = [cookies]
set_session_cookies(self._page.session, cookies)
def remove(self, name):
"""删除一个cookie
:param name: cookie的name字段
:return: None
"""
self._page.session.cookies.set(name, None)
def clear(self):
"""清除cookies"""
self._page.session.cookies.clear()

View File

@ -0,0 +1,30 @@
# -*- coding:utf-8 -*-
from http.cookiejar import Cookie
from typing import Union
from requests.cookies import RequestsCookieJar
from .._pages.session_page import SessionPage
from .._pages.chromium_base import ChromiumBase
class CookiesSetter(object):
def __init__(self, page: ChromiumBase):
self._page: ChromiumBase = ...
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
def remove(self, name: str, url: str = None, domain: str = None, path: str = None) -> None: ...
def clear(self) -> None: ...
class SessionCookiesSetter(object):
def __init__(self, page: SessionPage):
self._page: SessionPage = ...
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
def remove(self, name: str) -> None: ...
def clear(self) -> None: ...

View File

@ -11,7 +11,7 @@ from time import perf_counter, sleep
from requests.structures import CaseInsensitiveDict
from .._base.chromium_driver import ChromiumDriver
from .._base.driver import Driver
from .._functions.settings import Settings
from ..errors import WaitTimeoutError
@ -84,7 +84,7 @@ class Listener(object):
if self.listening:
return
self._driver = ChromiumDriver(self._target_id, 'page', self._address)
self._driver = Driver(self._target_id, 'page', self._address)
self._driver.run('Network.enable')
self._set_callback()
@ -222,7 +222,7 @@ class Listener(object):
debug = self._driver._debug
self._driver.stop()
if self.listening:
self._driver = ChromiumDriver(self._target_id, 'page', self._address)
self._driver = Driver(self._target_id, 'page', self._address)
self._driver._debug = debug
self._driver.run('Network.enable')
self._set_callback()

View File

@ -8,7 +8,7 @@ from typing import Union, Dict, List, Iterable, Tuple, Optional
from requests.structures import CaseInsensitiveDict
from .._base.chromium_driver import ChromiumDriver
from .._base.driver import Driver
from .._pages.chromium_base import ChromiumBase
from .._pages.chromium_frame import ChromiumFrame
@ -22,7 +22,7 @@ class Listener(object):
self._method: set = ...
self._caught: Queue = ...
self._is_regex: bool = ...
self._driver: ChromiumDriver = ...
self._driver: Driver = ...
self._request_ids: dict = ...
self._extra_info_ids: dict = ...
self.listening: bool = ...

View File

@ -251,7 +251,7 @@ class SelectElement(object):
:return: None
"""
if isinstance(option, (list, tuple, set)):
if not self.is_multi:
if not self.is_multi and len(option) > 1:
raise TypeError("只能对多项选框执行多选。")
for o in option:
o.run_js(f'this.selected={mode};')

View File

@ -7,8 +7,8 @@ from pathlib import Path
from requests.structures import CaseInsensitiveDict
from .cookies_setter import SessionCookiesSetter, CookiesSetter
from .._functions.tools import show_or_hide_browser
from .._functions.web import set_browser_cookies, set_session_cookies
class BasePageSetter(object):
@ -28,6 +28,7 @@ class BasePageSetter(object):
class ChromiumBaseSetter(BasePageSetter):
def __init__(self, page):
super().__init__(page)
self._cookies_setter = None
@property
def load_mode(self):
@ -39,6 +40,13 @@ class ChromiumBaseSetter(BasePageSetter):
"""返回用于设置页面滚动设置的对象"""
return PageScrollSetter(self._page.scroll)
@property
def cookies(self):
"""返回用于设置cookies的对象"""
if self._cookies_setter is None:
self._cookies_setter = CookiesSetter(self._page)
return self._cookies_setter
def retry_times(self, times):
"""设置连接失败重连次数"""
self._page.retry_times = times
@ -108,23 +116,6 @@ class ChromiumBaseSetter(BasePageSetter):
key=item, value=value)
self._page.run_cdp_loaded('DOMStorage.disable')
def cookie(self, cookie):
"""设置单个cookie
:param cookie: cookie信息
:return: None
"""
if isinstance(cookie, str):
self.cookies(cookie)
else:
self.cookies([cookie])
def cookies(self, cookies):
"""设置多个cookie注意不要传入单个
:param cookies: cookies信息
:return: None
"""
set_browser_cookies(self._page, cookies)
def upload_files(self, files):
"""等待上传的文件路径
:param files: 文件路径列表或字符串字符串时多个文件用回车分隔
@ -233,6 +224,14 @@ class SessionPageSetter(BasePageSetter):
:param page: SessionPage对象
"""
super().__init__(page)
self._cookies_setter = None
@property
def cookies(self):
"""返回用于设置cookies的对象"""
if self._cookies_setter is None:
self._cookies_setter = SessionCookiesSetter(self._page)
return self._cookies_setter
def retry_times(self, times):
"""设置连接失败时重连次数"""
@ -270,23 +269,6 @@ class SessionPageSetter(BasePageSetter):
if self._page.response:
self._page.response.encoding = encoding
def cookie(self, cookie):
"""为Session对象设置单个cookie
:param cookie: cookie信息
:return: None
"""
if isinstance(cookie, str):
self.cookies(cookie)
else:
self.cookies([cookie])
def cookies(self, cookies):
"""为Session对象设置多个cookie注意不要传入单个
:param cookies: cookies信息
:return: None
"""
set_session_cookies(self._page.session, cookies)
def headers(self, headers):
"""设置通用的headers
:param headers: dict形式的headers

View File

@ -3,14 +3,13 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from http.cookiejar import Cookie
from pathlib import Path
from typing import Union, Tuple, Literal, Any, Optional
from requests.adapters import HTTPAdapter
from requests.auth import HTTPBasicAuth
from requests.cookies import RequestsCookieJar
from .cookies_setter import SessionCookiesSetter, CookiesSetter
from .scroller import PageScroller
from .._base.base import BasePage
from .._elements.chromium_element import ChromiumElement
@ -34,6 +33,7 @@ class BasePageSetter(object):
class ChromiumBaseSetter(BasePageSetter):
def __init__(self, page):
self._page: ChromiumBase = ...
self._cookies_setter: CookiesSetter = ...
@property
def load_mode(self) -> LoadMode: ...
@ -41,6 +41,9 @@ class ChromiumBaseSetter(BasePageSetter):
@property
def scroll(self) -> PageScrollSetter: ...
@property
def cookies(self) -> CookiesSetter: ...
def retry_times(self, times: int) -> None: ...
def retry_interval(self, interval: float) -> None: ...
@ -53,10 +56,6 @@ class ChromiumBaseSetter(BasePageSetter):
def local_storage(self, item: str, value: Union[str, bool]) -> None: ...
def cookie(self, cookies: Union[RequestsCookieJar, str, dict]) -> None: ...
def cookies(self, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...
def headers(self, headers: dict) -> None: ...
def auto_handle_alert(self, on_off: bool = True, accept: bool = True) -> None: ...
@ -93,6 +92,10 @@ class ChromiumPageSetter(TabSetter):
class SessionPageSetter(BasePageSetter):
def __init__(self, page: SessionPage):
self._page: SessionPage = ...
self._cookies_setter: SessionCookiesSetter = ...
@property
def cookies(self) -> SessionCookiesSetter: ...
def retry_times(self, times: int) -> None: ...
@ -104,10 +107,6 @@ class SessionPageSetter(BasePageSetter):
def encoding(self, encoding: Optional[str, None], set_all: bool = True) -> None: ...
def cookie(self, cookie: Union[Cookie, str, dict]) -> None: ...
def cookies(self, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...
def headers(self, headers: dict) -> None: ...
def header(self, attr: str, value: str) -> None: ...

View File

@ -61,18 +61,14 @@ class ElementStates(object):
@property
def is_covered(self):
"""返回元素是否被覆盖,与是否在视口中无关"""
"""返回元素是否被覆盖,与是否在视口中无关如被覆盖返回覆盖元素的backend id否则返回False"""
lx, ly = self._ele.rect.click_point
try:
r = self._ele.page.run_cdp('DOM.getNodeForLocation', x=lx, y=ly)
bid = self._ele.page.run_cdp('DOM.getNodeForLocation', x=lx, y=ly).get('backendNodeId')
return bid if bid != self._ele._backend_id else False
except CDPError:
return False
if r.get('backendNodeId') != self._ele._backend_id:
return True
return False
@property
def has_rect(self):
"""返回元素是否拥有位置和大小没有返回False有返回四个角在页面中坐标组成的列表"""

View File

@ -3,7 +3,7 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from typing import Union, Tuple, List, Optional
from typing import Union, Tuple, List, Optional, Literal
from .._elements.chromium_element import ShadowRoot, ChromiumElement
from .._pages.chromium_base import ChromiumBase
@ -36,7 +36,7 @@ class ElementStates(object):
def is_whole_in_viewport(self) -> bool: ...
@property
def is_covered(self) -> bool: ...
def is_covered(self) -> Union[Literal[False], int]: ...
@property
def has_rect(self) -> Union[bool, List[Tuple[float, float]]]: ...