4.0.0b16(+)

timeouts的implicit改成base;
debugger_address改成address
ActionChains改成Actions;
一些文件和内部类改名;
wait.data_packets()即将废弃;
iframe切换了id也可继续监听;
修复监听器有时不能获取postData的问题;
修复监听器不能获取同域iframe数据包的问题;
修复等待数据包timeout无效问题
This commit is contained in:
g1879 2023-12-03 13:40:13 +08:00
parent 018c944405
commit 364700df2c
32 changed files with 227 additions and 150 deletions

View File

@ -13,4 +13,4 @@ from ._configs.chromium_options import ChromiumOptions
from ._configs.session_options import SessionOptions from ._configs.session_options import SessionOptions
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__'] __all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__']
__version__ = '4.0.0b15' __version__ = '4.0.0b16'

View File

@ -7,7 +7,7 @@ from time import sleep, perf_counter
from .chromium_driver import BrowserDriver, ChromiumDriver from .chromium_driver import BrowserDriver, ChromiumDriver
from .._commons.tools import stop_process_on_port, raise_error from .._commons.tools import stop_process_on_port, raise_error
from .._units.download_manager import DownloadManager from .._units.downloader import DownloadManager
__ERROR__ = 'error' __ERROR__ = 'error'

View File

@ -7,7 +7,7 @@ from typing import List, Optional, Union
from .chromium_driver import BrowserDriver, ChromiumDriver from .chromium_driver import BrowserDriver, ChromiumDriver
from .._pages.chromium_page import ChromiumPage from .._pages.chromium_page import ChromiumPage
from .._units.download_manager import DownloadManager from .._units.downloader import DownloadManager
class Browser(object): class Browser(object):

View File

@ -9,7 +9,7 @@ from threading import Thread, Event
from time import perf_counter from time import perf_counter
from requests import get from requests import get
from websocket import (WebSocketTimeoutException, WebSocketException, WebSocketConnectionClosedException, \ from websocket import (WebSocketTimeoutException, WebSocketException, WebSocketConnectionClosedException,
create_connection) create_connection)
@ -70,7 +70,7 @@ class ChromiumDriver(object):
self.method_results[ws_id] = Queue() self.method_results[ws_id] = Queue()
try: try:
self._ws.send(message_json) self._ws.send(message_json)
except OSError: except (OSError, WebSocketConnectionClosedException):
self.method_results.pop(ws_id, None) self.method_results.pop(ws_id, None)
return None return None
@ -190,14 +190,14 @@ class ChromiumDriver(object):
event = self.event_queue.get_nowait() event = self.event_queue.get_nowait()
function = self.event_handlers.get(event['method']) function = self.event_handlers.get(event['method'])
if function: if function:
if self._debug: # if self._debug:
print(f'开始执行 {function.__name__}') # print(f'开始执行 {function.__name__}')
try: try:
function(**event['params']) function(**event['params'])
except: except:
pass pass
if self._debug: # if self._debug:
print(f'执行 {function.__name__}完毕') # print(f'执行 {function.__name__}完毕')
self.event_handlers.clear() self.event_handlers.clear()
self.method_results.clear() self.method_results.clear()

View File

@ -24,10 +24,10 @@ def connect_browser(option):
:param option: ChromiumOptions对象 :param option: ChromiumOptions对象
:return: 返回是否接管的浏览器 :return: 返回是否接管的浏览器
""" """
debugger_address = option.debugger_address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') address = option.address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
chrome_path = option.browser_path chrome_path = option.browser_path
ip, port = debugger_address.split(':') ip, port = address.split(':')
if ip != '127.0.0.1' or port_is_using(ip, port) or option.is_existing_only: if ip != '127.0.0.1' or port_is_using(ip, port) or option.is_existing_only:
test_connect(ip, port) test_connect(ip, port)
option._headless = False option._headless = False
@ -86,7 +86,7 @@ def get_launch_args(opt):
result.add(i) result.add(i)
if not has_user_path and not opt.system_user_path: if not has_user_path and not opt.system_user_path:
port = opt.debugger_address.split(':')[-1] if opt.debugger_address else '0' port = opt.address.split(':')[-1] if opt.address else '0'
path = Path(gettempdir()) / 'DrissionPage' / f'userData_{port}' path = Path(gettempdir()) / 'DrissionPage' / f'userData_{port}'
path.mkdir(parents=True, exist_ok=True) path.mkdir(parents=True, exist_ok=True)
opt.set_user_data_path(path) opt.set_user_data_path(path)

View File

@ -4,6 +4,7 @@
@Contact : g1879@qq.com @Contact : g1879@qq.com
""" """
from pathlib import Path from pathlib import Path
from re import search
from shutil import rmtree from shutil import rmtree
from tempfile import gettempdir, TemporaryDirectory from tempfile import gettempdir, TemporaryDirectory
from threading import Lock from threading import Lock
@ -36,12 +37,13 @@ class ChromiumOptions(object):
self._extensions = options.get('extensions', []) self._extensions = options.get('extensions', [])
self._prefs = options.get('prefs', {}) self._prefs = options.get('prefs', {})
self._flags = options.get('flags', {}) self._flags = options.get('flags', {})
self._debugger_address = options.get('debugger_address', None) self._address = options.get('address', None)
self._load_mode = options.get('load_mode', 'normal') self._load_mode = options.get('load_mode', 'normal')
self._proxy = om.proxies.get('http', None)
self._system_user_path = options.get('system_user_path', False) self._system_user_path = options.get('system_user_path', False)
self._existing_only = options.get('existing_only', False) self._existing_only = options.get('existing_only', False)
self._proxy = om.proxies.get('http', None) or om.proxies.get('https', None)
user_path = user = False user_path = user = False
for arg in self._arguments: for arg in self._arguments:
if arg.startswith('--user-data-dir='): if arg.startswith('--user-data-dir='):
@ -54,14 +56,14 @@ class ChromiumOptions(object):
break break
timeouts = om.timeouts timeouts = om.timeouts
self._timeouts = {'implicit': timeouts['implicit'], self._timeouts = {'base': timeouts['base'],
'pageLoad': timeouts['page_load'], 'pageLoad': timeouts['page_load'],
'script': timeouts['script']} 'script': timeouts['script']}
self._auto_port = options.get('auto_port', False) self._auto_port = options.get('auto_port', False)
if self._auto_port: if self._auto_port:
port, path = PortFinder().get_port() port, path = PortFinder().get_port()
self._debugger_address = f'127.0.0.1:{port}' self._address = f'127.0.0.1:{port}'
self.set_argument('--user-data-dir', path) self.set_argument('--user-data-dir', path)
others = om.others others = om.others
@ -77,8 +79,8 @@ class ChromiumOptions(object):
self._extensions = [] self._extensions = []
self._prefs = {} self._prefs = {}
self._flags = {} self._flags = {}
self._timeouts = {'implicit': 10, 'pageLoad': 30, 'script': 30} self._timeouts = {'base': 10, 'pageLoad': 30, 'script': 30}
self._debugger_address = '127.0.0.1:9222' self._address = '127.0.0.1:9222'
self._load_mode = 'normal' self._load_mode = 'normal'
self._proxy = None self._proxy = None
self._auto_port = False self._auto_port = False
@ -125,12 +127,17 @@ class ChromiumOptions(object):
@property @property
def debugger_address(self): def debugger_address(self):
"""返回浏览器地址ip:port""" """返回浏览器地址ip:port"""
return self._debugger_address return self._address
@debugger_address.setter @debugger_address.setter
def debugger_address(self, address): def debugger_address(self, address):
"""设置浏览器地址格式ip:port""" """设置浏览器地址格式ip:port"""
self.set_debugger_address(address) self.set_address(address)
@property
def address(self):
"""返回浏览器地址ip:port"""
return self._address
@property @property
def arguments(self): def arguments(self):
@ -275,15 +282,16 @@ class ChromiumOptions(object):
self.clear_file_flags = True self.clear_file_flags = True
return self return self
def set_timeouts(self, implicit=None, pageLoad=None, script=None): def set_timeouts(self, base=None, pageLoad=None, script=None, implicit=None):
"""设置超时时间,单位为秒 """设置超时时间,单位为秒
:param implicit: 默认超时时间 :param base: 默认超时时间
:param pageLoad: 页面加载超时时间 :param pageLoad: 页面加载超时时间
:param script: 脚本运行超时时间 :param script: 脚本运行超时时间
:return: 当前对象 :return: 当前对象
""" """
if implicit is not None: base = base if base is not None else implicit
self._timeouts['implicit'] = implicit if base is not None:
self._timeouts['base'] = base
if pageLoad is not None: if pageLoad is not None:
self._timeouts['pageLoad'] = pageLoad self._timeouts['pageLoad'] = pageLoad
if script is not None: if script is not None:
@ -352,6 +360,10 @@ class ChromiumOptions(object):
:param proxy: 代理url和端口 :param proxy: 代理url和端口
:return: 当前对象 :return: 当前对象
""" """
if search(r'.*?:.*?@.*?\..*', proxy):
print('你似乎在设置使用账号密码的代理,暂时不支持这种代理,可自行用插件实现需求。')
if not proxy.lower().startswith('socks'):
print('你似乎在设置使用socks代理暂时不支持这种代理可自行用插件实现需求。')
self._proxy = proxy self._proxy = proxy
return self.set_argument('--proxy-server', proxy) return self.set_argument('--proxy-server', proxy)
@ -368,25 +380,26 @@ class ChromiumOptions(object):
self._load_mode = value.lower() self._load_mode = value.lower()
return self return self
def set_paths(self, browser_path=None, local_port=None, debugger_address=None, download_path=None, def set_paths(self, browser_path=None, local_port=None, address=None, download_path=None,
user_data_path=None, cache_path=None): user_data_path=None, cache_path=None, debugger_address=None):
"""快捷的路径设置函数 """快捷的路径设置函数
:param browser_path: 浏览器可执行文件路径 :param browser_path: 浏览器可执行文件路径
:param local_port: 本地端口号 :param local_port: 本地端口号
:param debugger_address: 调试浏览器地址127.0.0.1:9222 :param address: 调试浏览器地址127.0.0.1:9222
:param download_path: 下载文件路径 :param download_path: 下载文件路径
:param user_data_path: 用户数据路径 :param user_data_path: 用户数据路径
:param cache_path: 缓存路径 :param cache_path: 缓存路径
:return: 当前对象 :return: 当前对象
""" """
address = address or debugger_address
if browser_path is not None: if browser_path is not None:
self.set_browser_path(browser_path) self.set_browser_path(browser_path)
if local_port is not None: if local_port is not None:
self.set_local_port(local_port) self.set_local_port(local_port)
if debugger_address is not None: if address is not None:
self.set_debugger_address(debugger_address) self.set_address(address)
if download_path is not None: if download_path is not None:
self.set_download_path(download_path) self.set_download_path(download_path)
@ -404,17 +417,17 @@ class ChromiumOptions(object):
:param port: 端口号 :param port: 端口号
:return: 当前对象 :return: 当前对象
""" """
self._debugger_address = f'127.0.0.1:{port}' self._address = f'127.0.0.1:{port}'
self._auto_port = False self._auto_port = False
return self return self
def set_debugger_address(self, address): def set_address(self, address):
"""设置浏览器地址,格式'ip:port' """设置浏览器地址,格式'ip:port'
:param address: 浏览器地址 :param address: 浏览器地址
:return: 当前对象 :return: 当前对象
""" """
address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
self._debugger_address = address self._address = address
return self return self
def set_browser_path(self, path): def set_browser_path(self, path):
@ -507,7 +520,7 @@ class ChromiumOptions(object):
om = OptionsManager(self.ini_path or str(Path(__file__).parent / 'configs.ini')) om = OptionsManager(self.ini_path or str(Path(__file__).parent / 'configs.ini'))
# 设置chromium_options # 设置chromium_options
attrs = ('debugger_address', 'browser_path', 'arguments', 'extensions', 'user', 'load_mode', attrs = ('address', 'browser_path', 'arguments', 'extensions', 'user', 'load_mode',
'auto_port', 'system_user_path', 'existing_only', 'flags') 'auto_port', 'system_user_path', 'existing_only', 'flags')
for i in attrs: for i in attrs:
om.set_item('chromium_options', i, self.__getattribute__(f'_{i}')) om.set_item('chromium_options', i, self.__getattribute__(f'_{i}'))
@ -517,7 +530,7 @@ class ChromiumOptions(object):
# 设置路径 # 设置路径
om.set_item('paths', 'download_path', self._download_path or '') om.set_item('paths', 'download_path', self._download_path or '')
# 设置timeout # 设置timeout
om.set_item('timeouts', 'implicit', self._timeouts['implicit']) om.set_item('timeouts', 'base', self._timeouts['base'])
om.set_item('timeouts', 'page_load', self._timeouts['pageLoad']) om.set_item('timeouts', 'page_load', self._timeouts['pageLoad'])
om.set_item('timeouts', 'script', self._timeouts['script']) om.set_item('timeouts', 'script', self._timeouts['script'])
# 设置重试 # 设置重试

View File

@ -19,7 +19,7 @@ class ChromiumOptions(object):
self._load_mode: str = ... self._load_mode: str = ...
self._timeouts: dict = ... self._timeouts: dict = ...
self._proxy: str = ... self._proxy: str = ...
self._debugger_address: str = ... self._address: str = ...
self._extensions: list = ... self._extensions: list = ...
self._prefs: dict = ... self._prefs: dict = ...
self._flags: dict = ... self._flags: dict = ...
@ -54,7 +54,7 @@ class ChromiumOptions(object):
def proxy(self) -> str: ... def proxy(self) -> str: ...
@property @property
def debugger_address(self) -> str: ... def address(self) -> str: ...
@property @property
def arguments(self) -> list: ... def arguments(self) -> list: ...
@ -100,7 +100,7 @@ class ChromiumOptions(object):
def clear_flags_in_file(self) -> ChromiumOptions: ... def clear_flags_in_file(self) -> ChromiumOptions: ...
def set_timeouts(self, implicit: float = None, pageLoad: float = None, def set_timeouts(self, base: float = None, pageLoad: float = None,
script: float = None) -> ChromiumOptions: ... script: float = None) -> ChromiumOptions: ...
def set_user(self, user: str = 'Default') -> ChromiumOptions: ... def set_user(self, user: str = 'Default') -> ChromiumOptions: ...
@ -125,7 +125,7 @@ class ChromiumOptions(object):
def set_local_port(self, port: Union[str, int]) -> ChromiumOptions: ... def set_local_port(self, port: Union[str, int]) -> ChromiumOptions: ...
def set_debugger_address(self, address: str) -> ChromiumOptions: ... def set_address(self, address: str) -> ChromiumOptions: ...
def set_download_path(self, path: Union[str, Path]) -> ChromiumOptions: ... def set_download_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
@ -134,8 +134,8 @@ class ChromiumOptions(object):
def set_cache_path(self, path: Union[str, Path]) -> ChromiumOptions: ... def set_cache_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
def set_paths(self, browser_path: Union[str, Path] = None, local_port: Union[int, str] = None, def set_paths(self, browser_path: Union[str, Path] = None, local_port: Union[int, str] = None,
debugger_address: str = None, download_path: Union[str, Path] = None, address: str = None, download_path: Union[str, Path] = None, user_data_path: Union[str, Path] = None,
user_data_path: Union[str, Path] = None, cache_path: Union[str, Path] = None) -> ChromiumOptions: ... cache_path: Union[str, Path] = None) -> ChromiumOptions: ...
def use_system_user_path(self, on_off: bool = True) -> ChromiumOptions: ... def use_system_user_path(self, on_off: bool = True) -> ChromiumOptions: ...

View File

@ -2,7 +2,7 @@
download_path = download_path =
[chromium_options] [chromium_options]
debugger_address = 127.0.0.1:9222 address = 127.0.0.1:9222
browser_path = chrome browser_path = chrome
arguments = ['--no-first-run', '--disable-infobars', '--disable-popup-blocking'] arguments = ['--no-first-run', '--disable-infobars', '--disable-popup-blocking']
extensions = [] extensions = []
@ -18,7 +18,7 @@ existing_only = False
headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'} headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'}
[timeouts] [timeouts]
implicit = 10 base = 10
page_load = 30 page_load = 30
script = 30 script = 30

View File

@ -76,7 +76,7 @@ class SessionOptions(object):
self._max_redirects = options['max_redirects'] self._max_redirects = options['max_redirects']
self.set_proxies(om.proxies.get('http', None), om.proxies.get('https', None)) self.set_proxies(om.proxies.get('http', None), om.proxies.get('https', None))
self._timeout = om.timeouts.get('implicit', 10) self._timeout = om.timeouts.get('base', 10)
self._download_path = om.paths.get('download_path', None) or None self._download_path = om.paths.get('download_path', None) or None
others = om.others others = om.others
@ -379,7 +379,7 @@ class SessionOptions(object):
om.set_item('session_options', i, options[i]) om.set_item('session_options', i, options[i])
om.set_item('paths', 'download_path', self.download_path or '') om.set_item('paths', 'download_path', self.download_path or '')
om.set_item('timeouts', 'implicit', self.timeout) om.set_item('timeouts', 'base', self.timeout)
om.set_item('proxies', 'http', self.proxies.get('http', None)) om.set_item('proxies', 'http', self.proxies.get('http', None))
om.set_item('proxies', 'https', self.proxies.get('https', None)) om.set_item('proxies', 'https', self.proxies.get('https', None))
om.set_item('others', 'retry_times', self.retry_times) om.set_item('others', 'retry_times', self.retry_times)

View File

@ -19,7 +19,7 @@ from .._commons.web import make_absolute_link, get_ele_txt, format_html, is_js_f
from .._units.clicker import Clicker from .._units.clicker import Clicker
from .._units.rect import ElementRect from .._units.rect import ElementRect
from .._units.scroller import ElementScroller from .._units.scroller import ElementScroller
from .._units.select_element import SelectElement from .._units.selector import SelectElement
from .._units.setter import ChromiumElementSetter from .._units.setter import ChromiumElementSetter
from .._units.states import ElementStates, ShadowRootStates from .._units.states import ElementStates, ShadowRootStates
from .._units.waiter import ElementWaiter from .._units.waiter import ElementWaiter

View File

@ -16,7 +16,7 @@ from .._pages.web_page import WebPage
from .._units.clicker import Clicker from .._units.clicker import Clicker
from .._units.rect import ElementRect from .._units.rect import ElementRect
from .._units.scroller import ElementScroller from .._units.scroller import ElementScroller
from .._units.select_element import SelectElement from .._units.selector import SelectElement
from .._units.setter import ChromiumElementSetter from .._units.setter import ChromiumElementSetter
from .._units.states import ShadowRootStates, ElementStates from .._units.states import ShadowRootStates, ElementStates
from .._units.waiter import ElementWaiter from .._units.waiter import ElementWaiter

View File

@ -17,8 +17,8 @@ from .._commons.web import location_in_viewport
from .._elements.chromium_element import ChromiumElement, run_js, make_chromium_ele from .._elements.chromium_element import ChromiumElement, run_js, make_chromium_ele
from .._elements.none_element import NoneElement from .._elements.none_element import NoneElement
from .._elements.session_element import make_session_ele from .._elements.session_element import make_session_ele
from .._units.action_chains import ActionChains from .._units.actions import Actions
from .._units.network_listener import NetworkListener from .._units.listener import Listener
from .._units.rect import TabRect from .._units.rect import TabRect
from .._units.screencast import Screencast from .._units.screencast import Screencast
from .._units.scroller import PageScroller from .._units.scroller import PageScroller
@ -46,7 +46,6 @@ class ChromiumBase(BasePage):
self._set = None self._set = None
self._screencast = None self._screencast = None
self._actions = None self._actions = None
self._listener = None
self._states = None self._states = None
self._has_alert = False self._has_alert = False
self._ready_state = None self._ready_state = None
@ -57,6 +56,8 @@ class ChromiumBase(BasePage):
self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc
self._download_path = None self._download_path = None
self._load_end_time = 0 self._load_end_time = 0
if not hasattr(self, '_listener'):
self._listener = None
if isinstance(address, int) or (isinstance(address, str) and address.isdigit()): if isinstance(address, int) or (isinstance(address, str) and address.isdigit()):
address = f'127.0.0.1:{address}' address = f'127.0.0.1:{address}'
@ -313,7 +314,7 @@ class ChromiumBase(BasePage):
def actions(self): def actions(self):
"""返回用于执行动作链的对象""" """返回用于执行动作链的对象"""
if self._actions is None: if self._actions is None:
self._actions = ActionChains(self) self._actions = Actions(self)
self.wait.load_complete() self.wait.load_complete()
return self._actions return self._actions
@ -321,7 +322,7 @@ class ChromiumBase(BasePage):
def listen(self): def listen(self):
"""返回用于聆听数据包的对象""" """返回用于聆听数据包的对象"""
if self._listener is None: if self._listener is None:
self._listener = NetworkListener(self) self._listener = Listener(self)
return self._listener return self._listener
@property @property
@ -1054,20 +1055,21 @@ class ChromiumBase(BasePage):
class Timeout(object): class Timeout(object):
"""用于保存d模式timeout信息的类""" """用于保存d模式timeout信息的类"""
def __init__(self, page, implicit=None, page_load=None, script=None): def __init__(self, page, base=None, page_load=None, script=None, implicit=None):
""" """
:param page: ChromiumBase页面 :param page: ChromiumBase页面
:param implicit: 默认超时时间 :param base: 默认超时时间
:param page_load: 页面加载超时时间 :param page_load: 页面加载超时时间
:param script: js超时时间 :param script: js超时时间
""" """
self._page = page self._page = page
self.implicit = 10 if implicit is None else implicit base = base if base is not None else implicit
self.base = 10 if base is None else base
self.page_load = 30 if page_load is None else page_load self.page_load = 30 if page_load is None else page_load
self.script = 30 if script is None else script self.script = 30 if script is None else script
def __repr__(self): def __repr__(self):
return str({'implicit': self.implicit, 'page_load': self.page_load, 'script': self.script}) return str({'base': self.base, 'page_load': self.page_load, 'script': self.script})
class Alert(object): class Alert(object):

View File

@ -14,8 +14,8 @@ from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement from .._elements.session_element import SessionElement
from .._pages.chromium_frame import ChromiumFrame from .._pages.chromium_frame import ChromiumFrame
from .._pages.chromium_page import ChromiumPage from .._pages.chromium_page import ChromiumPage
from .._units.action_chains import ActionChains from .._units.actions import Actions
from .._units.network_listener import NetworkListener from .._units.listener import Listener
from .._units.rect import TabRect from .._units.rect import TabRect
from .._units.screencast import Screencast from .._units.screencast import Screencast
from .._units.scroller import Scroller, PageScroller from .._units.scroller import Scroller, PageScroller
@ -48,8 +48,8 @@ class ChromiumBase(BasePage):
self._wait: BaseWaiter = ... self._wait: BaseWaiter = ...
self._set: ChromiumBaseSetter = ... self._set: ChromiumBaseSetter = ...
self._screencast: Screencast = ... self._screencast: Screencast = ...
self._actions: ActionChains = ... self._actions: Actions = ...
self._listener: NetworkListener = ... self._listener: Listener = ...
self._states: PageStates = ... self._states: PageStates = ...
self._alert: Alert = ... self._alert: Alert = ...
self._has_alert: bool = ... self._has_alert: bool = ...
@ -152,10 +152,10 @@ class ChromiumBase(BasePage):
def screencast(self) -> Screencast: ... def screencast(self) -> Screencast: ...
@property @property
def actions(self) -> ActionChains: ... def actions(self) -> Actions: ...
@property @property
def listen(self) -> NetworkListener: ... def listen(self) -> Listener: ...
@property @property
def states(self) -> PageStates: ... def states(self) -> PageStates: ...
@ -237,9 +237,9 @@ class ChromiumBase(BasePage):
class Timeout(object): class Timeout(object):
def __init__(self, page: ChromiumBase, implicit=None, page_load=None, script=None): def __init__(self, page: ChromiumBase, base=None, page_load=None, script=None):
self._page: ChromiumBase = ... self._page: ChromiumBase = ...
self.implicit: float = ... self.base: float = ...
self.page_load: float = ... self.page_load: float = ...
self.script: float = ... self.script: float = ...

View File

@ -9,6 +9,7 @@ from time import sleep, perf_counter
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
from .._units.listener import FrameListener
from .._units.rect import FrameRect from .._units.rect import FrameRect
from .._units.scroller import FrameScroller from .._units.scroller import FrameScroller
from .._units.setter import ChromiumFrameSetter from .._units.setter import ChromiumFrameSetter
@ -122,12 +123,16 @@ class ChromiumFrame(ChromiumBase):
self._is_diff_domain = False self._is_diff_domain = False
self.doc_ele = ChromiumElement(self._target_page, backend_id=node['contentDocument']['backendNodeId']) self.doc_ele = ChromiumElement(self._target_page, backend_id=node['contentDocument']['backendNodeId'])
self._frame_id = node['frameId'] self._frame_id = node['frameId']
if self._listener:
self._listener._to_target(self._target_page.tab_id, self.address, self)
super().__init__(self.address, self._target_page.tab_id, self._target_page.timeout) super().__init__(self.address, self._target_page.tab_id, self._target_page.timeout)
self._debug = debug self._debug = debug
self.driver._debug = d_debug self.driver._debug = d_debug
else: else:
self._is_diff_domain = True self._is_diff_domain = True
if self._listener:
self._listener._to_target(node['frameId'], self.address, self)
super().__init__(self.address, node['frameId'], self._target_page.timeout) super().__init__(self.address, node['frameId'], self._target_page.timeout)
end_time = perf_counter() + self.timeouts.page_load end_time = perf_counter() + self.timeouts.page_load
while perf_counter() < end_time: while perf_counter() < end_time:
@ -251,6 +256,13 @@ class ChromiumFrame(ChromiumBase):
self._rect = FrameRect(self) self._rect = FrameRect(self)
return self._rect return self._rect
@property
def listen(self):
"""返回用于聆听数据包的对象"""
if self._listener is None:
self._listener = FrameListener(self)
return self._listener
# ----------挂件---------- # ----------挂件----------
@property @property

View File

@ -11,10 +11,11 @@ from .chromium_page import ChromiumPage
from .chromium_tab import ChromiumTab from .chromium_tab import ChromiumTab
from .web_page import WebPage from .web_page import WebPage
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._units.states import FrameStates from .._units.listener import FrameListener
from .._units.rect import FrameRect from .._units.rect import FrameRect
from .._units.scroller import FrameScroller from .._units.scroller import FrameScroller
from .._units.setter import ChromiumFrameSetter from .._units.setter import ChromiumFrameSetter
from .._units.states import FrameStates
from .._units.waiter import FrameWaiter from .._units.waiter import FrameWaiter
@ -33,6 +34,7 @@ class ChromiumFrame(ChromiumBase):
self._states: FrameStates = ... self._states: FrameStates = ...
self._reloading: bool = ... self._reloading: bool = ...
self._rect: FrameRect = ... self._rect: FrameRect = ...
self._listener: FrameListener = ...
def __call__(self, loc_or_str: Union[Tuple[str, str], str], def __call__(self, loc_or_str: Union[Tuple[str, str], str],
timeout: float = None) -> Union[ChromiumElement, str]: ... timeout: float = None) -> Union[ChromiumElement, str]: ...
@ -83,6 +85,9 @@ class ChromiumFrame(ChromiumBase):
@property @property
def rect(self) -> FrameRect: ... def rect(self) -> FrameRect: ...
@property
def listen(self) -> FrameListener: ...
@property @property
def _obj_id(self) -> str: ... def _obj_id(self) -> str: ...

View File

@ -32,7 +32,7 @@ class ChromiumPage(ChromiumBase):
address = self._handle_options(addr_or_opts) address = self._handle_options(addr_or_opts)
self._run_browser() self._run_browser()
super().__init__(address, tab_id) super().__init__(address, tab_id)
self.set.timeouts(implicit=timeout) self.set.timeouts(base=timeout)
self._page_init() self._page_init()
def _handle_options(self, addr_or_opts): def _handle_options(self, addr_or_opts):
@ -48,7 +48,7 @@ class ChromiumPage(ChromiumBase):
elif isinstance(addr_or_opts, str): elif isinstance(addr_or_opts, str):
self._chromium_options = ChromiumOptions() self._chromium_options = ChromiumOptions()
self._chromium_options.set_debugger_address(addr_or_opts) self._chromium_options.set_address(addr_or_opts)
elif isinstance(addr_or_opts, int): elif isinstance(addr_or_opts, int):
self._chromium_options = ChromiumOptions() self._chromium_options = ChromiumOptions()
@ -57,36 +57,36 @@ class ChromiumPage(ChromiumBase):
else: else:
raise TypeError('只能接收ip:port格式或ChromiumOptions类型参数。') raise TypeError('只能接收ip:port格式或ChromiumOptions类型参数。')
return self._chromium_options.debugger_address return self._chromium_options.address
def _run_browser(self): def _run_browser(self):
"""连接浏览器""" """连接浏览器"""
is_exist = connect_browser(self._chromium_options) is_exist = connect_browser(self._chromium_options)
try: try:
ws = get(f'http://{self._chromium_options.debugger_address}/json/version', headers={'Connection': 'close'}) ws = get(f'http://{self._chromium_options.address}/json/version', headers={'Connection': 'close'})
if not ws: if not ws:
raise BrowserConnectError('\n浏览器连接失败请检查是否启用全局代理。如是须设置不代理127.0.0.1地址。') raise BrowserConnectError('\n浏览器连接失败请检查是否启用全局代理。如是须设置不代理127.0.0.1地址。')
except : except :
raise BrowserConnectError('\n浏览器连接失败请检查是否启用全局代理。如是须设置不代理127.0.0.1地址。') raise BrowserConnectError('\n浏览器连接失败请检查是否启用全局代理。如是须设置不代理127.0.0.1地址。')
ws = ws.json()['webSocketDebuggerUrl'].split('/')[-1] ws = ws.json()['webSocketDebuggerUrl'].split('/')[-1]
self._browser = Browser(self._chromium_options.debugger_address, ws, self) self._browser = Browser(self._chromium_options.address, ws, self)
if (is_exist and self._chromium_options._headless is False and if (is_exist and self._chromium_options._headless is False and
'headless' in self._browser.run_cdp('Browser.getVersion')['userAgent'].lower()): 'headless' in self._browser.run_cdp('Browser.getVersion')['userAgent'].lower()):
self._browser.quit(3) self._browser.quit(3)
connect_browser(self._chromium_options) connect_browser(self._chromium_options)
ws = get(f'http://{self._chromium_options.debugger_address}/json/version', headers={'Connection': 'close'}) ws = get(f'http://{self._chromium_options.address}/json/version', headers={'Connection': 'close'})
ws = ws.json()['webSocketDebuggerUrl'].split('/')[-1] ws = ws.json()['webSocketDebuggerUrl'].split('/')[-1]
self._browser = Browser(self._chromium_options.debugger_address, ws, self) self._browser = Browser(self._chromium_options.address, ws, self)
def _d_set_runtime_settings(self): def _d_set_runtime_settings(self):
"""设置运行时用到的属性""" """设置运行时用到的属性"""
self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['pageLoad'], self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['pageLoad'],
script=self._chromium_options.timeouts['script'], script=self._chromium_options.timeouts['script'],
implicit=self._chromium_options.timeouts['implicit']) base=self._chromium_options.timeouts['base'])
if self._chromium_options.timeouts['implicit'] is not None: if self._chromium_options.timeouts['base'] is not None:
self._timeout = self._chromium_options.timeouts['implicit'] self._timeout = self._chromium_options.timeouts['base']
self._load_mode = self._chromium_options.load_mode self._load_mode = self._chromium_options.load_mode
self._download_path = None if self._chromium_options.download_path is None \ self._download_path = None if self._chromium_options.download_path is None \
else str(Path(self._chromium_options.download_path).absolute()) else str(Path(self._chromium_options.download_path).absolute())

View File

@ -174,7 +174,7 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
@property @property
def timeout(self): def timeout(self):
"""返回通用timeout设置""" """返回通用timeout设置"""
return self.timeouts.implicit return self.timeouts.base
@timeout.setter @timeout.setter
def timeout(self, second): def timeout(self, second):
@ -182,7 +182,7 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
:param second: 秒数 :param second: 秒数
:return: None :return: None
""" """
self.set.timeouts(implicit=second) self.set.timeouts(base=second)
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs): def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs):
"""跳转到一个url """跳转到一个url

View File

@ -32,7 +32,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
super().__init__(session_or_options=session_or_options) super().__init__(session_or_options=session_or_options)
if not chromium_options: if not chromium_options:
chromium_options = ChromiumOptions(read_file=chromium_options) chromium_options = ChromiumOptions(read_file=chromium_options)
chromium_options.set_timeouts(implicit=self._timeout).set_paths(download_path=self.download_path) chromium_options.set_timeouts(base=self._timeout).set_paths(download_path=self.download_path)
super(SessionPage, self).__init__(addr_or_opts=chromium_options, timeout=timeout) super(SessionPage, self).__init__(addr_or_opts=chromium_options, timeout=timeout)
self.change_mode(self._mode, go=False, copy_cookies=False) self.change_mode(self._mode, go=False, copy_cookies=False)
@ -138,7 +138,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
@property @property
def timeout(self): def timeout(self):
"""返回通用timeout设置""" """返回通用timeout设置"""
return self.timeouts.implicit return self.timeouts.base
@timeout.setter @timeout.setter
def timeout(self, second): def timeout(self, second):
@ -146,7 +146,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:param second: 秒数 :param second: 秒数
:return: None :return: None
""" """
self.set.timeouts(implicit=second) self.set.timeouts(base=second)
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs): def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs):
"""跳转到一个url """跳转到一个url

View File

@ -9,7 +9,7 @@ from .._commons.keys import modifierBit, keyDescriptionForString
from .._commons.web import location_in_viewport from .._commons.web import location_in_viewport
class ActionChains: class Actions:
"""用于实现动作链的类""" """用于实现动作链的类"""
def __init__(self, page): def __init__(self, page):

View File

@ -10,7 +10,7 @@ from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
class ActionChains: class Actions:
def __init__(self, page: ChromiumBase): def __init__(self, page: ChromiumBase):
self.page: ChromiumBase = ... self.page: ChromiumBase = ...
@ -20,53 +20,53 @@ class ActionChains:
self.curr_y: int = ... self.curr_y: int = ...
def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[int, int], str], def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[int, int], str],
offset_x: int = 0, offset_y: int = 0, duration: float = .5) -> ActionChains: ... offset_x: int = 0, offset_y: int = 0, duration: float = .5) -> Actions: ...
def move(self, offset_x: int = 0, offset_y: int = 0, duration: float = .5) -> ActionChains: ... def move(self, offset_x: int = 0, offset_y: int = 0, duration: float = .5) -> Actions: ...
def click(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def r_click(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def r_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def m_click(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def m_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def db_click(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def db_click(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def hold(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def release(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def r_hold(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def r_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def r_release(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def r_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def m_hold(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def m_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def m_release(self, on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... def m_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def _hold(self, on_ele: Union[ChromiumElement, str] = None, button: str = 'left', def _hold(self, on_ele: Union[ChromiumElement, str] = None, button: str = 'left',
count: int = 1) -> ActionChains: ... count: int = 1) -> Actions: ...
def _release(self, button: str) -> ActionChains: ... def _release(self, button: str) -> Actions: ...
def scroll(self, delta_x: int = 0, delta_y: int = 0, def scroll(self, delta_x: int = 0, delta_y: int = 0,
on_ele: Union[ChromiumElement, str] = None) -> ActionChains: ... on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
def up(self, pixel: int) -> ActionChains: ... def up(self, pixel: int) -> Actions: ...
def down(self, pixel: int) -> ActionChains: ... def down(self, pixel: int) -> Actions: ...
def left(self, pixel: int) -> ActionChains: ... def left(self, pixel: int) -> Actions: ...
def right(self, pixel: int) -> ActionChains: ... def right(self, pixel: int) -> Actions: ...
def key_down(self, key: str) -> ActionChains: ... def key_down(self, key: str) -> Actions: ...
def key_up(self, key: str) -> ActionChains: ... def key_up(self, key: str) -> Actions: ...
def type(self, text: Union[str, list, tuple]) -> ActionChains: ... def type(self, text: Union[str, list, tuple]) -> Actions: ...
def wait(self, second: float) -> ActionChains: ... def wait(self, second: float) -> Actions: ...
def _get_key_data(self, key: str, action: str) -> dict: ... def _get_key_data(self, key: str, action: str) -> dict: ...

View File

@ -14,7 +14,7 @@ from requests.structures import CaseInsensitiveDict
from .._base.chromium_driver import ChromiumDriver from .._base.chromium_driver import ChromiumDriver
class NetworkListener(object): class Listener(object):
"""监听器基类""" """监听器基类"""
def __init__(self, page): def __init__(self, page):
@ -22,6 +22,8 @@ class NetworkListener(object):
:param page: ChromiumBase对象 :param page: ChromiumBase对象
""" """
self._page = page self._page = page
self._address = page.address
self._target_id = page._target_id
self._driver = None self._driver = None
self._caught = None # 临存捕捉到的数据 self._caught = None # 临存捕捉到的数据
@ -77,7 +79,7 @@ class NetworkListener(object):
if self.listening: if self.listening:
return return
self._driver = ChromiumDriver(self._page.tab_id, 'page', self._page.address) self._driver = ChromiumDriver(self._target_id, 'page', self._address)
self._driver.run('Network.enable') self._driver.run('Network.enable')
self.listening = True self.listening = True
@ -102,7 +104,7 @@ class NetworkListener(object):
fail = False fail = False
else: else:
end = perf_counter() + count end = perf_counter() + timeout
while True: while True:
if perf_counter() > end: if perf_counter() > end:
fail = True fail = True
@ -179,6 +181,26 @@ class NetworkListener(object):
self._extra_info_ids = {} self._extra_info_ids = {}
self._caught.queue.clear() self._caught.queue.clear()
def _to_target(self, target_id, address, page):
"""切换监听的页面对象
:param target_id: 新页面对象_target_id
:param address: 新页面对象address
:param page: 新页面对象
:return: None
"""
self._target_id = target_id
self._address = address
self._page = page
debug = False
if self._driver:
debug = self._driver._debug
self._driver.stop()
if self.listening:
self._driver = ChromiumDriver(self._target_id, 'page', self._address)
self._driver._debug = debug
self._driver.run('Network.enable')
self._set_callback()
def _set_callback(self): def _set_callback(self):
"""设置监听请求的回调函数""" """设置监听请求的回调函数"""
self._driver.set_callback('Network.requestWillBeSent', self._requestWillBeSent) self._driver.set_callback('Network.requestWillBeSent', self._requestWillBeSent)
@ -190,8 +212,6 @@ class NetworkListener(object):
def _requestWillBeSent(self, **kwargs): def _requestWillBeSent(self, **kwargs):
"""接收到请求时的回调函数""" """接收到请求时的回调函数"""
if kwargs.get('frameId', self._page._frame_id) != self._page._frame_id:
return
p = None p = None
if not self._targets: if not self._targets:
if not self._method or kwargs['request']['method'] in self._method: if not self._method or kwargs['request']['method'] in self._method:
@ -210,9 +230,6 @@ class NetworkListener(object):
not self._method or kwargs['request']['method'] in self._method): not self._method or kwargs['request']['method'] in self._method):
p = self._request_ids.setdefault(rid, DataPacket(self._page.tab_id, target)) p = self._request_ids.setdefault(rid, DataPacket(self._page.tab_id, target))
p._raw_request = kwargs p._raw_request = kwargs
if kwargs['request'].get('hasPostData', None) and not kwargs['request'].get('postData', None):
p._raw_post_data = self._driver.run('Network.getRequestPostData',
requestId=rid)['postData']
break break
self._extra_info_ids.setdefault(kwargs['requestId'], {})['obj'] = p if p else False self._extra_info_ids.setdefault(kwargs['requestId'], {})['obj'] = p if p else False
@ -223,8 +240,6 @@ class NetworkListener(object):
def _response_received(self, **kwargs): def _response_received(self, **kwargs):
"""接收到返回信息时处理方法""" """接收到返回信息时处理方法"""
if kwargs.get('frameId', self._page._frame_id) != self._page._frame_id:
return
request = self._request_ids.get(kwargs['requestId'], None) request = self._request_ids.get(kwargs['requestId'], None)
if request: if request:
request._raw_response = kwargs['response'] request._raw_response = kwargs['response']
@ -238,7 +253,7 @@ class NetworkListener(object):
if obj is False: if obj is False:
self._extra_info_ids.pop(kwargs['requestId'], None) self._extra_info_ids.pop(kwargs['requestId'], None)
elif isinstance(obj, DataPacket): elif isinstance(obj, DataPacket):
obj._requestExtraInfo = r['request'] obj._requestExtraInfo = r.get('request', None)
obj._responseExtraInfo = kwargs obj._responseExtraInfo = kwargs
self._extra_info_ids.pop(kwargs['requestId'], None) self._extra_info_ids.pop(kwargs['requestId'], None)
else: else:
@ -246,16 +261,21 @@ class NetworkListener(object):
def _loading_finished(self, **kwargs): def _loading_finished(self, **kwargs):
"""请求完成时处理方法""" """请求完成时处理方法"""
r_id = kwargs['requestId'] rid = kwargs['requestId']
dp = self._request_ids.get(r_id) packet = self._request_ids.get(rid)
if dp: if packet:
r = self._driver.run('Network.getResponseBody', requestId=r_id) r = self._driver.run('Network.getResponseBody', requestId=rid)
if 'body' in r: if 'body' in r:
dp._raw_body = r['body'] packet._raw_body = r['body']
dp._base64_body = r['base64Encoded'] packet._base64_body = r['base64Encoded']
else: else:
dp._raw_body = '' packet._raw_body = ''
dp._base64_body = False packet._base64_body = False
if (packet._raw_request['request'].get('hasPostData', None)
and not packet._raw_request['request'].get('postData', None)):
r = self._driver.run('Network.getRequestPostData', requestId=rid, _timeout=1)
packet._raw_post_data = r.get('postData', None)
r = self._extra_info_ids.get(kwargs['requestId'], None) r = self._extra_info_ids.get(kwargs['requestId'], None)
if r: if r:
@ -268,10 +288,10 @@ class NetworkListener(object):
obj._responseExtraInfo = response obj._responseExtraInfo = response
self._extra_info_ids.pop(kwargs['requestId'], None) self._extra_info_ids.pop(kwargs['requestId'], None)
self._request_ids.pop(r_id, None) self._request_ids.pop(rid, None)
if dp: if packet:
self._caught.put(dp) self._caught.put(packet)
def _loading_failed(self, **kwargs): def _loading_failed(self, **kwargs):
"""请求失败时的回调方法""" """请求失败时的回调方法"""
@ -299,6 +319,20 @@ class NetworkListener(object):
self._caught.put(dp) self._caught.put(dp)
class FrameListener(Listener):
def _requestWillBeSent(self, **kwargs):
"""接收到请求时的回调函数"""
if not self._page._is_diff_domain and kwargs.get('frameId', None) != self._page._frame_id:
return
super()._requestWillBeSent(**kwargs)
def _response_received(self, **kwargs):
"""接收到返回信息时处理方法"""
if not self._page._is_diff_domain and kwargs.get('frameId', None) != self._page._frame_id:
return
super()._response_received(**kwargs)
class DataPacket(object): class DataPacket(object):
"""返回的数据包管理类""" """返回的数据包管理类"""

View File

@ -10,11 +10,14 @@ from requests.structures import CaseInsensitiveDict
from .._base.chromium_driver import ChromiumDriver from .._base.chromium_driver import ChromiumDriver
from .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
from .._pages.chromium_frame import ChromiumFrame
class NetworkListener(object): class Listener(object):
def __init__(self, page: ChromiumBase): def __init__(self, page: ChromiumBase):
self._page: ChromiumBase = ... self._page: ChromiumBase = ...
self._address: str = ...
self._target_id: str = ...
self._targets: Union[str, dict] = ... self._targets: Union[str, dict] = ...
self._method: set = ... self._method: set = ...
self._caught: Queue = ... self._caught: Queue = ...
@ -44,6 +47,8 @@ class NetworkListener(object):
def clear(self) -> None: ... def clear(self) -> None: ...
def _to_target(self, target_id: str, address: str, page: ChromiumBase) -> None: ...
def start(self, targets: Union[str, List[str], Tuple, bool, None] = None, is_regex: bool = False, def start(self, targets: Union[str, List[str], Tuple, bool, None] = None, is_regex: bool = False,
method: Union[str, list, tuple, set] = None) \ method: Union[str, list, tuple, set] = None) \
-> Union[DataPacket, Dict[str, List[DataPacket]], False]: ... -> Union[DataPacket, Dict[str, List[DataPacket]], False]: ...
@ -66,6 +71,12 @@ class NetworkListener(object):
def _set_callback(self) -> None: ... def _set_callback(self) -> None: ...
class FrameListener(Listener):
def __init__(self, page: ChromiumFrame, is_diff: bool):
self._page: ChromiumFrame = ...
self._is_diff: bool = ...
class DataPacket(object): class DataPacket(object):
"""返回的数据包管理类""" """返回的数据包管理类"""

View File

@ -47,16 +47,17 @@ class ChromiumBaseSetter(BasePageSetter):
"""设置连接失败重连间隔""" """设置连接失败重连间隔"""
self._page.retry_interval = interval self._page.retry_interval = interval
def timeouts(self, implicit=None, page_load=None, script=None): def timeouts(self, base=None, page_load=None, script=None, implicit=None):
"""设置超时时间,单位为秒 """设置超时时间,单位为秒
:param implicit: 查找元素超时时间 :param base: 基本等待时间除页面加载和脚本超时其它等待默认使用
:param page_load: 页面加载超时时间 :param page_load: 页面加载超时时间
:param script: 脚本运行超时时间 :param script: 脚本运行超时时间
:return: None :return: None
""" """
if implicit is not None: base = base if base is not None else implicit
self._page.timeouts.implicit = implicit if base is not None:
self._page._timeout = implicit self._page.timeouts.base = base
self._page._timeout = base
if page_load is not None: if page_load is not None:
self._page.timeouts.page_load = page_load self._page.timeouts.page_load = page_load

View File

@ -45,7 +45,7 @@ class ChromiumBaseSetter(BasePageSetter):
def retry_interval(self, interval: float) -> None: ... def retry_interval(self, interval: float) -> None: ...
def timeouts(self, implicit: float = None, page_load: float = None, script: float = None) -> None: ... def timeouts(self, base: float = None, page_load: float = None, script: float = None) -> None: ...
def user_agent(self, ua: str, platform: str = None) -> None: ... def user_agent(self, ua: str, platform: str = None) -> None: ...

View File

@ -130,14 +130,6 @@ class BaseWaiter(object):
""" """
return self._change('title', text, exclude, timeout, raise_err) return self._change('title', text, exclude, timeout, raise_err)
def data_packets(self, count=1, timeout=None, fix_count: bool = True):
"""等待符合要求的数据包到达指定数量
:param count: 需要捕捉的数据包数量
:param timeout: 超时时间为None无限等待
:param fix_count: 是否必须满足总数要求发生超时为True返回False为False返回已捕捉到的数据包
:return: count为1时返回数据包对象大于1时返回列表超时且fix_count为True时返回False"""
return self._driver.listen.wait(count, timeout, fix_count)
def _change(self, arg, text, exclude=False, timeout=None, raise_err=None): def _change(self, arg, text, exclude=False, timeout=None, raise_err=None):
"""等待指定属性变成包含或不包含指定文本 """等待指定属性变成包含或不包含指定文本
:param arg: 要被匹配的属性 :param arg: 要被匹配的属性
@ -189,6 +181,16 @@ class BaseWaiter(object):
else: else:
return False return False
# -----------即将废弃-----------
def data_packets(self, count=1, timeout=None, fix_count: bool = True):
"""等待符合要求的数据包到达指定数量
:param count: 需要捕捉的数据包数量
:param timeout: 超时时间为None无限等待
:param fix_count: 是否必须满足总数要求发生超时为True返回False为False返回已捕捉到的数据包
:return: count为1时返回数据包对象大于1时返回列表超时且fix_count为True时返回False"""
return self._driver.listen.wait(count, timeout, fix_count)
class TabWaiter(BaseWaiter): class TabWaiter(BaseWaiter):

View File

@ -5,8 +5,8 @@
""" """
from typing import Union, List from typing import Union, List
from .download_manager import DownloadMission from .downloader import DownloadMission
from .network_listener import DataPacket from .listener import DataPacket
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
from .._pages.chromium_frame import ChromiumFrame from .._pages.chromium_frame import ChromiumFrame
@ -47,9 +47,6 @@ class BaseWaiter(object):
def title_change(self, text: str, exclude: bool = False, timeout: float = None, raise_err: bool = None) -> bool: ... def title_change(self, text: str, exclude: bool = False, timeout: float = None, raise_err: bool = None) -> bool: ...
def data_packets(self, count: int = 1, timeout: float = None,
fix_count: bool = True) -> Union[List[DataPacket], DataPacket, None]: ...
def _change(self, arg: str, text: str, exclude: bool = False, timeout: float = None, def _change(self, arg: str, text: str, exclude: bool = False, timeout: float = None,
raise_err: bool = None) -> bool: ... raise_err: bool = None) -> bool: ...

View File

@ -8,6 +8,6 @@ from ._commons.keys import Keys
from ._commons.settings import Settings from ._commons.settings import Settings
from ._commons.tools import wait_until, configs_to_here from ._commons.tools import wait_until, configs_to_here
from ._elements.session_element import make_session_ele from ._elements.session_element import make_session_ele
from ._units.action_chains import ActionChains from ._units.actions import Actions
__all__ = ['make_session_ele', 'ActionChains', 'Keys', 'By', 'Settings', 'wait_until', 'configs_to_here'] __all__ = ['make_session_ele', 'Actions', 'Keys', 'By', 'Settings', 'wait_until', 'configs_to_here']

View File

@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh:
setup( setup(
name="DrissionPage", name="DrissionPage",
version="4.0.0b15", version="4.0.0b16",
author="g1879", author="g1879",
author_email="g1879@qq.com", author_email="g1879@qq.com",
description="Python based web automation tool. It can control the browser and send and receive data packets.", description="Python based web automation tool. It can control the browser and send and receive data packets.",