mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
不少修改(+)
修复一个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:
parent
35c25fa454
commit
05cac3b69a
@ -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):
|
||||
|
@ -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: ...
|
||||
|
||||
|
@ -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):
|
@ -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): ...
|
@ -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]],
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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: ...
|
||||
|
@ -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 = ...
|
||||
|
@ -37,7 +37,7 @@ class ChromiumPage(ChromiumBase):
|
||||
|
||||
def _handle_options(self, addr_or_opts):
|
||||
"""设置浏览器启动属性
|
||||
:param addr_or_opts: 'ip:port'、ChromiumOptions、ChromiumDriver
|
||||
:param addr_or_opts: 'ip:port'、ChromiumOptions、Driver
|
||||
:return: 返回浏览器地址
|
||||
"""
|
||||
if not addr_or_opts:
|
||||
|
@ -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
|
||||
|
@ -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): ...
|
||||
|
@ -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 = ...
|
||||
|
@ -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: 模拟点击的超时时间,等待元素可见、可用、进入视口
|
||||
|
@ -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: ...
|
||||
|
||||
|
64
DrissionPage/_units/cookies_setter.py
Normal file
64
DrissionPage/_units/cookies_setter.py
Normal 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()
|
30
DrissionPage/_units/cookies_setter.pyi
Normal file
30
DrissionPage/_units/cookies_setter.pyi
Normal 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: ...
|
@ -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()
|
||||
|
@ -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 = ...
|
||||
|
@ -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};')
|
||||
|
@ -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
|
||||
|
@ -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: ...
|
||||
|
@ -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,有返回四个角在页面中坐标组成的列表"""
|
||||
|
@ -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]]]: ...
|
||||
|
Loading…
x
Reference in New Issue
Block a user