mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
元素动作返回元素自己;修改NoneElement打印的值;修复is_displayed参数有时不正确问题
This commit is contained in:
parent
cdced6e8d7
commit
99f2de7e5b
@ -13,10 +13,6 @@ from .options_manage import OptionsManager
|
||||
|
||||
class ChromiumOptions(object):
|
||||
def __init__(self, read_file=True, ini_path=None):
|
||||
"""
|
||||
:param read_file: 是否从默认ini文件中读取配置信息
|
||||
:param ini_path: ini文件路径,为None则读取默认ini文件
|
||||
"""
|
||||
self._user_data_path = None
|
||||
self._user = 'Default'
|
||||
self._prefs_to_del = []
|
||||
@ -82,105 +78,81 @@ class ChromiumOptions(object):
|
||||
|
||||
@property
|
||||
def download_path(self):
|
||||
"""默认下载路径文件路径"""
|
||||
return self._download_path
|
||||
|
||||
@property
|
||||
def browser_path(self):
|
||||
"""浏览器启动文件路径"""
|
||||
return self._browser_path
|
||||
|
||||
@property
|
||||
def user_data_path(self):
|
||||
"""返回用户数据文件夹路径"""
|
||||
return self._user_data_path
|
||||
|
||||
@property
|
||||
def tmp_path(self):
|
||||
"""返回临时文件夹路径"""
|
||||
return self._tmp_path
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
"""返回用户配置文件夹名称"""
|
||||
return self._user
|
||||
|
||||
@property
|
||||
def load_mode(self):
|
||||
"""返回页面加载策略,'normal', 'eager', 'none'"""
|
||||
return self._load_mode
|
||||
|
||||
@property
|
||||
def timeouts(self):
|
||||
"""返回timeouts设置"""
|
||||
return self._timeouts
|
||||
|
||||
@property
|
||||
def proxy(self):
|
||||
"""返回代理设置"""
|
||||
return self._proxy
|
||||
|
||||
@property
|
||||
def address(self):
|
||||
"""返回浏览器地址,ip:port"""
|
||||
return self._address
|
||||
|
||||
@property
|
||||
def arguments(self):
|
||||
"""返回浏览器命令行设置列表"""
|
||||
return self._arguments
|
||||
|
||||
@property
|
||||
def extensions(self):
|
||||
"""以list形式返回要加载的插件路径"""
|
||||
return self._extensions
|
||||
|
||||
@property
|
||||
def preferences(self):
|
||||
"""返回用户首选项配置"""
|
||||
return self._prefs
|
||||
|
||||
@property
|
||||
def flags(self):
|
||||
"""返回实验项配置"""
|
||||
return self._flags
|
||||
|
||||
@property
|
||||
def system_user_path(self):
|
||||
"""返回是否使用系统安装的浏览器所使用的用户数据文件夹"""
|
||||
return self._system_user_path
|
||||
|
||||
@property
|
||||
def is_existing_only(self):
|
||||
"""返回是否只接管现有浏览器方式"""
|
||||
return self._existing_only
|
||||
|
||||
@property
|
||||
def is_auto_port(self):
|
||||
"""返回是否使用自动端口和用户文件,如指定范围则返回范围tuple"""
|
||||
return self._auto_port
|
||||
|
||||
@property
|
||||
def retry_times(self):
|
||||
"""返回连接失败时的重试次数"""
|
||||
return self._retry_times
|
||||
|
||||
@property
|
||||
def retry_interval(self):
|
||||
"""返回连接失败时的重试间隔(秒)"""
|
||||
return self._retry_interval
|
||||
|
||||
@property
|
||||
def is_headless(self):
|
||||
"""返回是否无头模式"""
|
||||
return self._is_headless
|
||||
|
||||
def set_retry(self, times=None, interval=None):
|
||||
"""设置连接失败时的重试操作
|
||||
:param times: 重试次数
|
||||
:param interval: 重试间隔
|
||||
:return: 当前对象
|
||||
"""
|
||||
if times is not None:
|
||||
self._retry_times = times
|
||||
if interval is not None:
|
||||
@ -188,11 +160,6 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def set_argument(self, arg, value=None):
|
||||
"""设置浏览器配置的argument属性
|
||||
:param arg: 属性名
|
||||
:param value: 属性值,有值的属性传入值,没有的传入None,如传入False,删除该项
|
||||
:return: 当前对象
|
||||
"""
|
||||
self.remove_argument(arg)
|
||||
if value is not False:
|
||||
if arg == '--headless':
|
||||
@ -211,10 +178,6 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def remove_argument(self, value):
|
||||
"""移除一个argument项
|
||||
:param value: 设置项名,有值的设置项传入设置名称即可
|
||||
:return: 当前对象
|
||||
"""
|
||||
elements_to_delete = [arg for arg in self._arguments if arg == value or arg.startswith(f'{value}=')]
|
||||
if not elements_to_delete:
|
||||
return self
|
||||
@ -227,10 +190,6 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def add_extension(self, path):
|
||||
"""添加插件
|
||||
:param path: 插件路径,可指向文件夹
|
||||
:return: 当前对象
|
||||
"""
|
||||
path = Path(path)
|
||||
if not path.exists():
|
||||
raise OSError('插件路径不存在。')
|
||||
@ -238,43 +197,22 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def remove_extensions(self):
|
||||
"""移除所有插件
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._extensions = []
|
||||
return self
|
||||
|
||||
def set_pref(self, arg, value):
|
||||
"""设置Preferences文件中的用户设置项
|
||||
:param arg: 设置项名称
|
||||
:param value: 设置项值
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._prefs[arg] = value
|
||||
return self
|
||||
|
||||
def remove_pref(self, arg):
|
||||
"""删除用户首选项设置,不能删除已设置到文件中的项
|
||||
:param arg: 设置项名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._prefs.pop(arg, None)
|
||||
return self
|
||||
|
||||
def remove_pref_from_file(self, arg):
|
||||
"""删除用户配置文件中已设置的项
|
||||
:param arg: 设置项名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._prefs_to_del.append(arg)
|
||||
return self
|
||||
|
||||
def set_flag(self, flag, value=None):
|
||||
"""设置实验项
|
||||
:param flag: 设置项名称
|
||||
:param value: 设置项的值,为False则删除该项
|
||||
:return: 当前对象
|
||||
"""
|
||||
if value is False:
|
||||
self._flags.pop(flag, None)
|
||||
else:
|
||||
@ -282,32 +220,22 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def clear_flags_in_file(self):
|
||||
"""删除浏览器配置文件中已设置的实验项"""
|
||||
self.clear_file_flags = True
|
||||
return self
|
||||
|
||||
def clear_flags(self):
|
||||
"""清空本对象已设置的flag参数"""
|
||||
self._flags = {}
|
||||
return self
|
||||
|
||||
def clear_arguments(self):
|
||||
"""清空本对象已设置的argument参数"""
|
||||
self._arguments = []
|
||||
return self
|
||||
|
||||
def clear_prefs(self):
|
||||
"""清空本对象已设置的pref参数"""
|
||||
self._prefs = {}
|
||||
return self
|
||||
|
||||
def set_timeouts(self, base=None, page_load=None, script=None):
|
||||
"""设置超时时间,单位为秒
|
||||
:param base: 默认超时时间
|
||||
:param page_load: 页面加载超时时间
|
||||
:param script: 脚本运行超时时间
|
||||
:return: 当前对象
|
||||
"""
|
||||
if base is not None:
|
||||
self._timeouts['base'] = base
|
||||
if page_load is not None:
|
||||
@ -318,82 +246,42 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def set_user(self, user='Default'):
|
||||
"""设置使用哪个用户配置文件夹
|
||||
:param user: 用户文件夹名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
self.set_argument('--profile-directory', user)
|
||||
self._user = user
|
||||
return self
|
||||
|
||||
def headless(self, on_off=True):
|
||||
"""设置是否隐藏浏览器界面
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = 'new' if on_off else on_off
|
||||
return self.set_argument('--headless', on_off)
|
||||
|
||||
def no_imgs(self, on_off=True):
|
||||
"""设置是否加载图片
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = None if on_off else False
|
||||
return self.set_argument('--blink-settings=imagesEnabled=false', on_off)
|
||||
|
||||
def no_js(self, on_off=True):
|
||||
"""设置是否禁用js
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = None if on_off else False
|
||||
return self.set_argument('--disable-javascript', on_off)
|
||||
|
||||
def mute(self, on_off=True):
|
||||
"""设置是否静音
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = None if on_off else False
|
||||
return self.set_argument('--mute-audio', on_off)
|
||||
|
||||
def incognito(self, on_off=True):
|
||||
"""设置是否使用无痕模式启动
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = None if on_off else False
|
||||
return self.set_argument('--incognito', on_off)
|
||||
|
||||
def new_env(self, on_off=True):
|
||||
"""设置是否使用全新浏览器环境
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._new_env = on_off
|
||||
return self
|
||||
|
||||
def ignore_certificate_errors(self, on_off=True):
|
||||
"""设置是否忽略证书错误
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
on_off = None if on_off else False
|
||||
return self.set_argument('--ignore-certificate-errors', on_off)
|
||||
|
||||
def set_user_agent(self, user_agent):
|
||||
"""设置user agent
|
||||
:param user_agent: user agent文本
|
||||
:return: 当前对象
|
||||
"""
|
||||
return self.set_argument('--user-agent', user_agent)
|
||||
|
||||
def set_proxy(self, proxy):
|
||||
"""设置代理
|
||||
:param proxy: 代理url和端口
|
||||
:return: 当前对象
|
||||
"""
|
||||
if search(r'.*?:.*?@.*?\..*', proxy):
|
||||
print('你似乎在设置使用账号密码的代理,暂时不支持这种代理,可自行用插件实现需求。')
|
||||
if proxy.lower().startswith('socks'):
|
||||
@ -402,13 +290,6 @@ class ChromiumOptions(object):
|
||||
return self.set_argument('--proxy-server', proxy)
|
||||
|
||||
def set_load_mode(self, value):
|
||||
"""设置load_mode,可接收 'normal', 'eager', 'none'
|
||||
normal:默认情况下使用, 等待所有资源下载完成
|
||||
eager:DOM访问已准备就绪, 但其他资源 (如图像) 可能仍在加载中
|
||||
none:完全不阻塞
|
||||
:param value: 可接收 'normal', 'eager', 'none'
|
||||
:return: 当前对象
|
||||
"""
|
||||
if value not in ('normal', 'eager', 'none'):
|
||||
raise ValueError("只能选择 'normal', 'eager', 'none'。")
|
||||
self._load_mode = value.lower()
|
||||
@ -446,52 +327,28 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def set_local_port(self, port):
|
||||
"""设置本地启动端口
|
||||
:param port: 端口号
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._address = f'127.0.0.1:{port}'
|
||||
self._auto_port = False
|
||||
return self
|
||||
|
||||
def set_address(self, address):
|
||||
"""设置浏览器地址,格式'ip:port'
|
||||
:param address: 浏览器地址
|
||||
:return: 当前对象
|
||||
"""
|
||||
address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
|
||||
self._address = address
|
||||
return self
|
||||
|
||||
def set_browser_path(self, path):
|
||||
"""设置浏览器可执行文件路径
|
||||
:param path: 浏览器路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._browser_path = str(path)
|
||||
return self
|
||||
|
||||
def set_download_path(self, path):
|
||||
"""设置下载文件保存路径
|
||||
:param path: 下载路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._download_path = '.' if path is None else str(path)
|
||||
return self
|
||||
|
||||
def set_tmp_path(self, path):
|
||||
"""设置临时文件文件保存路径
|
||||
:param path: 下载路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._tmp_path = str(path)
|
||||
return self
|
||||
|
||||
def set_user_data_path(self, path):
|
||||
"""设置用户文件夹路径
|
||||
:param path: 用户文件夹路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
u = str(path)
|
||||
self.set_argument('--user-data-dir', u)
|
||||
self._user_data_path = u
|
||||
@ -499,27 +356,14 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def set_cache_path(self, path):
|
||||
"""设置缓存路径
|
||||
:param path: 缓存路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
self.set_argument('--disk-cache-dir', str(path))
|
||||
return self
|
||||
|
||||
def use_system_user_path(self, on_off=True):
|
||||
"""设置是否使用系统安装的浏览器默认用户文件夹
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._system_user_path = on_off
|
||||
return self
|
||||
|
||||
def auto_port(self, on_off=True, scope=None):
|
||||
"""自动获取可用端口
|
||||
:param on_off: 是否开启自动获取端口号
|
||||
:param scope: 指定端口范围,不含最后的数字,为None则使用[9600-59600)
|
||||
:return: 当前对象
|
||||
"""
|
||||
if on_off:
|
||||
self._auto_port = scope if scope else (9600, 59600)
|
||||
else:
|
||||
@ -527,18 +371,10 @@ class ChromiumOptions(object):
|
||||
return self
|
||||
|
||||
def existing_only(self, on_off=True):
|
||||
"""设置只接管已有浏览器,不自动启动新的
|
||||
:param on_off: 是否开启自动获取端口号
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._existing_only = on_off
|
||||
return self
|
||||
|
||||
def save(self, path=None):
|
||||
"""保存设置到文件
|
||||
:param path: ini文件的路径, None 保存到当前读取的配置文件,传入 'default' 保存到默认ini文件
|
||||
:return: 保存文件的绝对路径
|
||||
"""
|
||||
if path == 'default':
|
||||
path = (Path(__file__).parent / 'configs.ini').absolute()
|
||||
|
||||
@ -585,7 +421,6 @@ class ChromiumOptions(object):
|
||||
return path
|
||||
|
||||
def save_to_default(self):
|
||||
"""保存当前配置到默认ini文件"""
|
||||
return self.save('default')
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -36,144 +36,368 @@ class ChromiumOptions(object):
|
||||
_is_headless: bool = ...
|
||||
_ua_set: bool = ...
|
||||
|
||||
def __init__(self, read_file: [bool, None] = True, ini_path: Union[str, Path] = None): ...
|
||||
def __init__(self,
|
||||
read_file: [bool, None] = True,
|
||||
ini_path: Union[str, Path] = None):
|
||||
"""
|
||||
:param read_file: 是否从默认ini文件中读取配置信息
|
||||
:param ini_path: ini文件路径,为None则读取默认ini文件
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def download_path(self) -> str: ...
|
||||
def download_path(self) -> str:
|
||||
"""默认下载路径文件路径"""
|
||||
...
|
||||
|
||||
@property
|
||||
def browser_path(self) -> str: ...
|
||||
def browser_path(self) -> str:
|
||||
"""浏览器启动文件路径"""
|
||||
...
|
||||
|
||||
@property
|
||||
def user_data_path(self) -> str: ...
|
||||
def user_data_path(self) -> str:
|
||||
"""返回用户数据文件夹路径"""
|
||||
...
|
||||
|
||||
@property
|
||||
def tmp_path(self) -> Optional[str]: ...
|
||||
def tmp_path(self) -> Optional[str]:
|
||||
"""返回临时文件夹路径"""
|
||||
...
|
||||
|
||||
@property
|
||||
def user(self) -> str: ...
|
||||
def user(self) -> str:
|
||||
"""返回用户配置文件夹名称"""
|
||||
...
|
||||
|
||||
@property
|
||||
def load_mode(self) -> str: ...
|
||||
def load_mode(self) -> str:
|
||||
"""返回页面加载策略,'normal', 'eager', 'none'"""
|
||||
...
|
||||
|
||||
@property
|
||||
def timeouts(self) -> dict: ...
|
||||
def timeouts(self) -> dict:
|
||||
"""返回timeouts设置"""
|
||||
...
|
||||
|
||||
@property
|
||||
def proxy(self) -> str: ...
|
||||
def proxy(self) -> str:
|
||||
"""返回代理设置"""
|
||||
...
|
||||
|
||||
@property
|
||||
def address(self) -> str: ...
|
||||
def address(self) -> str:
|
||||
"""返回浏览器地址,ip:port"""
|
||||
...
|
||||
|
||||
@property
|
||||
def arguments(self) -> list: ...
|
||||
def arguments(self) -> list:
|
||||
"""返回浏览器命令行设置列表"""
|
||||
...
|
||||
|
||||
@property
|
||||
def extensions(self) -> list: ...
|
||||
def extensions(self) -> list:
|
||||
"""以list形式返回要加载的插件路径"""
|
||||
...
|
||||
|
||||
@property
|
||||
def preferences(self) -> dict: ...
|
||||
def preferences(self) -> dict:
|
||||
"""返回用户首选项配置"""
|
||||
...
|
||||
|
||||
@property
|
||||
def flags(self) -> dict: ...
|
||||
def flags(self) -> dict:
|
||||
"""返回实验项配置"""
|
||||
...
|
||||
|
||||
@property
|
||||
def system_user_path(self) -> bool: ...
|
||||
def system_user_path(self) -> bool:
|
||||
"""返回是否使用系统安装的浏览器所使用的用户数据文件夹"""
|
||||
...
|
||||
|
||||
@property
|
||||
def is_existing_only(self) -> bool: ...
|
||||
def is_existing_only(self) -> bool:
|
||||
"""返回是否只接管现有浏览器方式"""
|
||||
...
|
||||
|
||||
@property
|
||||
def is_auto_port(self) -> Union[bool, Tuple[int, int]]: ...
|
||||
def is_auto_port(self) -> Union[bool, Tuple[int, int]]:
|
||||
"""返回是否使用自动端口和用户文件,如指定范围则返回范围tuple"""
|
||||
...
|
||||
|
||||
@property
|
||||
def retry_times(self) -> int: ...
|
||||
def retry_times(self) -> int:
|
||||
"""返回连接失败时的重试次数"""
|
||||
...
|
||||
|
||||
@property
|
||||
def retry_interval(self) -> float: ...
|
||||
def retry_interval(self) -> float:
|
||||
"""返回连接失败时的重试间隔(秒)"""
|
||||
...
|
||||
|
||||
@property
|
||||
def is_headless(self) -> bool: ...
|
||||
def is_headless(self) -> bool:
|
||||
"""返回是否无头模式"""
|
||||
...
|
||||
|
||||
def set_retry(self, times: int = None, interval: float = None) -> ChromiumOptions: ...
|
||||
def set_retry(self, times: int = None, interval: float = None) -> ChromiumOptions:
|
||||
"""设置连接失败时的重试操作
|
||||
:param times: 重试次数
|
||||
:param interval: 重试间隔
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_argument(self, arg: str, value: Union[str, None, bool] = None) -> ChromiumOptions: ...
|
||||
def set_argument(self, arg: str, value: Union[str, None, bool] = None) -> ChromiumOptions:
|
||||
"""设置浏览器配置的argument属性
|
||||
:param arg: 属性名
|
||||
:param value: 属性值,有值的属性传入值,没有的传入None,如传入False,删除该项
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_argument(self, value: str) -> ChromiumOptions: ...
|
||||
def remove_argument(self, value: str) -> ChromiumOptions:
|
||||
"""移除一个argument项
|
||||
:param value: 设置项名,有值的设置项传入设置名称即可
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def add_extension(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def add_extension(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""添加插件
|
||||
:param path: 插件路径,可指向文件夹
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_extensions(self) -> ChromiumOptions: ...
|
||||
def remove_extensions(self) -> ChromiumOptions:
|
||||
"""移除所有插件
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_pref(self, arg: str, value: Any) -> ChromiumOptions: ...
|
||||
def set_pref(self, arg: str, value: Any) -> ChromiumOptions:
|
||||
"""设置Preferences文件中的用户设置项
|
||||
:param arg: 设置项名称
|
||||
:param value: 设置项值
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_pref(self, arg: str) -> ChromiumOptions: ...
|
||||
def remove_pref(self, arg: str) -> ChromiumOptions:
|
||||
"""删除用户首选项设置,不能删除已设置到文件中的项
|
||||
:param arg: 设置项名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_pref_from_file(self, arg: str) -> ChromiumOptions: ...
|
||||
def remove_pref_from_file(self, arg: str) -> ChromiumOptions:
|
||||
"""删除用户配置文件中已设置的项
|
||||
:param arg: 设置项名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_flag(self, flag: str, value: Union[int, str, bool] = None) -> ChromiumOptions: ...
|
||||
def set_flag(self, flag: str, value: Union[int, str, bool] = None) -> ChromiumOptions:
|
||||
"""设置实验项
|
||||
:param flag: 设置项名称
|
||||
:param value: 设置项的值,为False则删除该项
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def clear_flags_in_file(self) -> ChromiumOptions: ...
|
||||
def clear_flags_in_file(self) -> ChromiumOptions:
|
||||
"""删除浏览器配置文件中已设置的实验项"""
|
||||
...
|
||||
|
||||
def clear_flags(self) -> ChromiumOptions: ...
|
||||
def clear_flags(self) -> ChromiumOptions:
|
||||
"""清空本对象已设置的flag参数"""
|
||||
...
|
||||
|
||||
def clear_arguments(self) -> ChromiumOptions: ...
|
||||
def clear_arguments(self) -> ChromiumOptions:
|
||||
"""清空本对象已设置的argument参数"""
|
||||
...
|
||||
|
||||
def clear_prefs(self) -> ChromiumOptions: ...
|
||||
def clear_prefs(self) -> ChromiumOptions:
|
||||
"""清空本对象已设置的pref参数"""
|
||||
...
|
||||
|
||||
def set_timeouts(self,
|
||||
base: float = None,
|
||||
page_load: float = None,
|
||||
script: float = None) -> ChromiumOptions: ...
|
||||
script: float = None) -> ChromiumOptions:
|
||||
"""设置超时时间,单位为秒
|
||||
:param base: 默认超时时间
|
||||
:param page_load: 页面加载超时时间
|
||||
:param script: 脚本运行超时时间
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_user(self, user: str = 'Default') -> ChromiumOptions: ...
|
||||
def set_user(self, user: str = 'Default') -> ChromiumOptions:
|
||||
"""设置使用哪个用户配置文件夹
|
||||
:param user: 用户文件夹名称
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def headless(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def headless(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否隐藏浏览器界面
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def no_imgs(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def no_imgs(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否加载图片
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def no_js(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def no_js(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否禁用js
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def mute(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def mute(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否静音
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def incognito(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def incognito(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否使用无痕模式启动
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def new_env(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def new_env(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置是否使用全新浏览器环境
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_user_agent(self, user_agent: str) -> ChromiumOptions: ...
|
||||
def ignore_certificate_errors(self, on_off=True) -> ChromiumOptions:
|
||||
"""设置是否忽略证书错误
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_proxy(self, proxy: str) -> ChromiumOptions: ...
|
||||
def set_user_agent(self, user_agent: str) -> ChromiumOptions:
|
||||
"""设置user agent
|
||||
:param user_agent: user agent文本
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def ignore_certificate_errors(self, on_off=True) -> ChromiumOptions: ...
|
||||
def set_proxy(self, proxy: str) -> ChromiumOptions:
|
||||
"""设置代理
|
||||
:param proxy: 代理url和端口
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_load_mode(self, value: Literal['normal', 'eager', 'none']) -> ChromiumOptions: ...
|
||||
def set_load_mode(self, value: Literal['normal', 'eager', 'none']) -> ChromiumOptions:
|
||||
"""设置load_mode,可接收 'normal', 'eager', 'none'
|
||||
normal:默认情况下使用, 等待所有资源下载完成
|
||||
eager:DOM访问已准备就绪, 但其他资源 (如图像) 可能仍在加载中
|
||||
none:完全不阻塞
|
||||
:param value: 可接收 'normal', 'eager', 'none'
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_browser_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def set_local_port(self, port: Union[str, int]) -> ChromiumOptions:
|
||||
"""设置本地启动端口
|
||||
:param port: 端口号
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_local_port(self, port: Union[str, int]) -> ChromiumOptions: ...
|
||||
def set_address(self, address: str) -> ChromiumOptions:
|
||||
"""设置浏览器地址,格式'ip:port'
|
||||
:param address: 浏览器地址
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_address(self, address: str) -> ChromiumOptions: ...
|
||||
def set_browser_path(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""设置浏览器可执行文件路径
|
||||
:param path: 浏览器路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_download_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def set_download_path(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""设置下载文件保存路径
|
||||
:param path: 下载路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_tmp_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def set_tmp_path(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""设置临时文件文件保存路径
|
||||
:param path: 下载路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_user_data_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def set_user_data_path(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""设置用户文件夹路径
|
||||
:param path: 用户文件夹路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_cache_path(self, path: Union[str, Path]) -> ChromiumOptions: ...
|
||||
def set_cache_path(self, path: Union[str, Path]) -> ChromiumOptions:
|
||||
"""设置缓存路径
|
||||
:param path: 缓存路径
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_paths(self, browser_path: Union[str, Path] = None, local_port: Union[int, str] = None,
|
||||
address: str = None, download_path: Union[str, Path] = None, user_data_path: Union[str, Path] = None,
|
||||
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:
|
||||
"""设置是否使用系统安装的浏览器默认用户文件夹
|
||||
:param on_off: 开或关
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def auto_port(self,
|
||||
on_off: bool = True,
|
||||
scope: Tuple[int, int] = None) -> ChromiumOptions: ...
|
||||
scope: Tuple[int, int] = None) -> ChromiumOptions:
|
||||
"""自动获取可用端口
|
||||
:param on_off: 是否开启自动获取端口号
|
||||
:param scope: 指定端口范围,不含最后的数字,为None则使用[9600-59600)
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def existing_only(self, on_off: bool = True) -> ChromiumOptions: ...
|
||||
def existing_only(self, on_off: bool = True) -> ChromiumOptions:
|
||||
"""设置只接管已有浏览器,不自动启动新的
|
||||
:param on_off: 是否开启自动获取端口号
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def save(self, path: Union[str, Path] = None) -> str: ...
|
||||
def save(self, path: Union[str, Path] = None) -> str:
|
||||
"""保存设置到文件
|
||||
:param path: ini文件的路径, None 保存到当前读取的配置文件,传入 'default' 保存到默认ini文件
|
||||
:return: 保存文件的绝对路径
|
||||
"""
|
||||
...
|
||||
|
||||
def save_to_default(self) -> str: ...
|
||||
def save_to_default(self) -> str:
|
||||
"""保存当前配置到默认ini文件"""
|
||||
...
|
||||
|
@ -14,9 +14,6 @@ class OptionsManager(object):
|
||||
"""管理配置文件内容的类"""
|
||||
|
||||
def __init__(self, path=None):
|
||||
"""初始化,读取配置文件,如没有设置临时文件夹,则设置并新建
|
||||
:param path: ini文件的路径,为None则找项目文件夹下的,找不到则读取模块文件夹下的
|
||||
"""
|
||||
if path is False:
|
||||
self.ini_path = None
|
||||
else:
|
||||
@ -79,18 +76,9 @@ class OptionsManager(object):
|
||||
self.set_item('others', 'retry_interval', '2')
|
||||
|
||||
def __getattr__(self, item):
|
||||
"""以dict形似返回获取大项信息
|
||||
:param item: 项名
|
||||
:return: None
|
||||
"""
|
||||
return self.get_option(item)
|
||||
|
||||
def get_value(self, section, item):
|
||||
"""获取配置的值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:return: 项值
|
||||
"""
|
||||
try:
|
||||
return eval(self._conf.get(section, item))
|
||||
except (SyntaxError, NameError):
|
||||
@ -99,10 +87,6 @@ class OptionsManager(object):
|
||||
return None
|
||||
|
||||
def get_option(self, section):
|
||||
"""把section内容以字典方式返回
|
||||
:param section: 段名
|
||||
:return: 段内容生成的字典
|
||||
"""
|
||||
items = self._conf.items(section)
|
||||
option = dict()
|
||||
|
||||
@ -115,30 +99,15 @@ class OptionsManager(object):
|
||||
return option
|
||||
|
||||
def set_item(self, section, item, value):
|
||||
"""设置配置值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:param value: 项值
|
||||
:return: None
|
||||
"""
|
||||
self._conf.set(section, item, str(value))
|
||||
self.__setattr__(f'_{section}', None)
|
||||
return self
|
||||
|
||||
def remove_item(self, section, item):
|
||||
"""删除配置值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:return: None
|
||||
"""
|
||||
self._conf.remove_option(section, item)
|
||||
return self
|
||||
|
||||
def save(self, path=None):
|
||||
"""保存配置文件
|
||||
:param path: ini文件的路径,传入 'default' 保存到默认ini文件
|
||||
:return: 保存路径
|
||||
"""
|
||||
default_path = (Path(__file__).parent / 'configs.ini').absolute()
|
||||
if path == 'default':
|
||||
path = default_path
|
||||
@ -163,11 +132,9 @@ class OptionsManager(object):
|
||||
return path
|
||||
|
||||
def save_to_default(self):
|
||||
"""保存当前配置到默认ini文件"""
|
||||
return self.save('default')
|
||||
|
||||
def show(self):
|
||||
"""打印所有设置信息"""
|
||||
for i in self._conf.sections():
|
||||
print(f'[{i}]')
|
||||
pprint(self.get_option(i))
|
||||
|
@ -15,20 +15,62 @@ class OptionsManager(object):
|
||||
file_exists: bool = ...
|
||||
_conf: RawConfigParser = ...
|
||||
|
||||
def __init__(self, path: Union[Path, str] = None): ...
|
||||
def __init__(self, path: Union[Path, str] = None):
|
||||
"""初始化,读取配置文件,如没有设置临时文件夹,则设置并新建
|
||||
:param path: ini文件的路径,为None则找项目文件夹下的,找不到则读取模块文件夹下的
|
||||
"""
|
||||
...
|
||||
|
||||
def __getattr__(self, item) -> dict: ...
|
||||
def __getattr__(self, item) -> dict:
|
||||
"""以dict形似返回获取大项信息
|
||||
:param item: 项名
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def get_value(self, section: str, item: str) -> Any: ...
|
||||
def get_value(self, section: str, item: str) -> Any:
|
||||
"""获取配置的值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:return: 项值
|
||||
"""
|
||||
...
|
||||
|
||||
def get_option(self, section: str) -> dict: ...
|
||||
def get_option(self, section: str) -> dict:
|
||||
"""把section内容以字典方式返回
|
||||
:param section: 段名
|
||||
:return: 段内容生成的字典
|
||||
"""
|
||||
...
|
||||
|
||||
def set_item(self, section: str, item: str, value: Any) -> None: ...
|
||||
def set_item(self, section: str, item: str, value: Any) -> None:
|
||||
"""设置配置值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:param value: 项值
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_item(self, section: str, item: str) -> None: ...
|
||||
def remove_item(self, section: str, item: str) -> None:
|
||||
"""删除配置值
|
||||
:param section: 段名
|
||||
:param item: 项名
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def save(self, path: str = None) -> str: ...
|
||||
def save(self, path: str = None) -> str:
|
||||
"""保存配置文件
|
||||
:param path: ini文件的路径,传入 'default' 保存到默认ini文件
|
||||
:return: 保存路径
|
||||
"""
|
||||
...
|
||||
|
||||
def save_to_default(self) -> str: ...
|
||||
def save_to_default(self) -> str:
|
||||
"""保存当前配置到默认ini文件"""
|
||||
...
|
||||
|
||||
def show(self) -> None: ...
|
||||
def show(self) -> None:
|
||||
"""打印所有设置信息"""
|
||||
...
|
||||
|
@ -17,13 +17,8 @@ from .._functions.web import format_headers
|
||||
|
||||
|
||||
class SessionOptions(object):
|
||||
"""requests的Session对象配置类"""
|
||||
|
||||
def __init__(self, read_file=True, ini_path=None):
|
||||
"""
|
||||
:param read_file: 是否从文件读取配置
|
||||
:param ini_path: ini文件路径
|
||||
"""
|
||||
self.ini_path = None
|
||||
self._download_path = '.'
|
||||
self._timeout = 10
|
||||
@ -93,62 +88,39 @@ class SessionOptions(object):
|
||||
# ===========须独立处理的项开始============
|
||||
@property
|
||||
def download_path(self):
|
||||
"""返回默认下载路径属性信息"""
|
||||
return self._download_path
|
||||
|
||||
def set_download_path(self, path):
|
||||
"""设置默认下载路径
|
||||
:param path: 下载路径
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._download_path = '.' if path is None else str(path)
|
||||
return self
|
||||
|
||||
@property
|
||||
def timeout(self):
|
||||
"""返回timeout属性信息"""
|
||||
return self._timeout
|
||||
|
||||
def set_timeout(self, second):
|
||||
"""设置超时信息
|
||||
:param second: 秒数
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._timeout = second
|
||||
return self
|
||||
|
||||
@property
|
||||
def proxies(self):
|
||||
"""返回proxies设置信息"""
|
||||
if self._proxies is None:
|
||||
self._proxies = {}
|
||||
return self._proxies
|
||||
|
||||
def set_proxies(self, http=None, https=None):
|
||||
"""设置proxies参数
|
||||
:param http: http代理地址
|
||||
:param https: https代理地址
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('proxies', {'http': http, 'https': https})
|
||||
return self
|
||||
|
||||
@property
|
||||
def retry_times(self):
|
||||
"""返回连接失败时的重试次数"""
|
||||
return self._retry_times
|
||||
|
||||
@property
|
||||
def retry_interval(self):
|
||||
"""返回连接失败时的重试间隔(秒)"""
|
||||
return self._retry_interval
|
||||
|
||||
def set_retry(self, times=None, interval=None):
|
||||
"""设置连接失败时的重试操作
|
||||
:param times: 重试次数
|
||||
:param interval: 重试间隔
|
||||
:return: 当前对象
|
||||
"""
|
||||
if times is not None:
|
||||
self._retry_times = times
|
||||
if interval is not None:
|
||||
@ -159,16 +131,11 @@ class SessionOptions(object):
|
||||
|
||||
@property
|
||||
def headers(self):
|
||||
"""返回headers设置信息"""
|
||||
if self._headers is None:
|
||||
self._headers = {}
|
||||
return self._headers
|
||||
|
||||
def set_headers(self, headers):
|
||||
"""设置headers参数
|
||||
:param headers: 参数值,传入None可在ini文件标记删除
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
if headers is None:
|
||||
self._headers = None
|
||||
self._del_set.add('headers')
|
||||
@ -178,11 +145,6 @@ class SessionOptions(object):
|
||||
return self
|
||||
|
||||
def set_a_header(self, name, value):
|
||||
"""设置headers中一个项
|
||||
:param name: 设置名称
|
||||
:param value: 设置值
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
if self._headers is None:
|
||||
self._headers = {}
|
||||
|
||||
@ -190,10 +152,6 @@ class SessionOptions(object):
|
||||
return self
|
||||
|
||||
def remove_a_header(self, name):
|
||||
"""从headers中删除一个设置
|
||||
:param name: 要删除的设置
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
if self._headers is None:
|
||||
return self
|
||||
|
||||
@ -202,156 +160,99 @@ class SessionOptions(object):
|
||||
return self
|
||||
|
||||
def clear_headers(self):
|
||||
"""清空已设置的header参数"""
|
||||
self._headers = None
|
||||
self._del_set.add('headers')
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
"""以list形式返回cookies"""
|
||||
if self._cookies is None:
|
||||
self._cookies = []
|
||||
return self._cookies
|
||||
|
||||
def set_cookies(self, cookies):
|
||||
"""设置一个或多个cookies信息
|
||||
:param cookies: cookies,可为Cookie, CookieJar, list, tuple, str, dict,传入None可在ini文件标记删除
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
cookies = cookies if cookies is None else list(cookies_to_tuple(cookies))
|
||||
self._sets('cookies', cookies)
|
||||
return self
|
||||
|
||||
@property
|
||||
def auth(self):
|
||||
"""返回认证设置信息"""
|
||||
return self._auth
|
||||
|
||||
def set_auth(self, auth):
|
||||
"""设置认证元组或对象
|
||||
:param auth: 认证元组或对象
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('auth', auth)
|
||||
return self
|
||||
|
||||
@property
|
||||
def hooks(self):
|
||||
"""返回回调方法"""
|
||||
if self._hooks is None:
|
||||
self._hooks = {}
|
||||
return self._hooks
|
||||
|
||||
def set_hooks(self, hooks):
|
||||
"""设置回调方法
|
||||
:param hooks: 回调方法
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._hooks = hooks
|
||||
return self
|
||||
|
||||
@property
|
||||
def params(self):
|
||||
"""返回连接参数设置信息"""
|
||||
if self._params is None:
|
||||
self._params = {}
|
||||
return self._params
|
||||
|
||||
def set_params(self, params):
|
||||
"""设置查询参数字典
|
||||
:param params: 查询参数字典
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('params', params)
|
||||
return self
|
||||
|
||||
@property
|
||||
def verify(self):
|
||||
"""返回是否验证SSL证书设置"""
|
||||
return self._verify
|
||||
|
||||
def set_verify(self, on_off):
|
||||
"""设置是否验证SSL证书
|
||||
:param on_off: 是否验证 SSL 证书
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('verify', on_off)
|
||||
return self
|
||||
|
||||
@property
|
||||
def cert(self):
|
||||
"""返回SSL证书设置信息"""
|
||||
return self._cert
|
||||
|
||||
def set_cert(self, cert):
|
||||
"""SSL客户端证书文件的路径(.pem格式),或(‘cert’, ‘key’)元组
|
||||
:param cert: 证书路径或元组
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('cert', cert)
|
||||
return self
|
||||
|
||||
@property
|
||||
def adapters(self):
|
||||
"""返回适配器设置信息"""
|
||||
if self._adapters is None:
|
||||
self._adapters = []
|
||||
return self._adapters
|
||||
|
||||
def add_adapter(self, url, adapter):
|
||||
"""添加适配器
|
||||
:param url: 适配器对应url
|
||||
:param adapter: 适配器对象
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._adapters.append((url, adapter))
|
||||
return self
|
||||
|
||||
@property
|
||||
def stream(self):
|
||||
"""返回是否使用流式响应内容设置信息"""
|
||||
return self._stream
|
||||
|
||||
def set_stream(self, on_off):
|
||||
"""设置是否使用流式响应内容
|
||||
:param on_off: 是否使用流式响应内容
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('stream', on_off)
|
||||
return self
|
||||
|
||||
@property
|
||||
def trust_env(self):
|
||||
"""返回是否信任环境设置信息"""
|
||||
return self._trust_env
|
||||
|
||||
def set_trust_env(self, on_off):
|
||||
"""设置是否信任环境
|
||||
:param on_off: 是否信任环境
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('trust_env', on_off)
|
||||
return self
|
||||
|
||||
@property
|
||||
def max_redirects(self):
|
||||
"""返回最大重定向次数"""
|
||||
return self._max_redirects
|
||||
|
||||
def set_max_redirects(self, times):
|
||||
"""设置最大重定向次数
|
||||
:param times: 最大重定向次数
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
self._sets('max_redirects', times)
|
||||
return self
|
||||
|
||||
def _sets(self, arg, val):
|
||||
"""给属性赋值或标记删除
|
||||
:param arg: 属性名称
|
||||
:param val: 参数值
|
||||
:return: None
|
||||
"""
|
||||
if val is None:
|
||||
self.__setattr__(f'_{arg}', None)
|
||||
self._del_set.add(arg)
|
||||
@ -361,10 +262,6 @@ class SessionOptions(object):
|
||||
self._del_set.remove(arg)
|
||||
|
||||
def save(self, path=None):
|
||||
"""保存设置到文件
|
||||
:param path: ini文件的路径,传入 'default' 保存到默认ini文件
|
||||
:return: 保存文件的绝对路径
|
||||
"""
|
||||
if path == 'default':
|
||||
path = (Path(__file__).parent / 'configs.ini').absolute()
|
||||
|
||||
@ -412,15 +309,12 @@ class SessionOptions(object):
|
||||
return path
|
||||
|
||||
def save_to_default(self):
|
||||
"""保存当前配置到默认ini文件"""
|
||||
return self.save('default')
|
||||
|
||||
def as_dict(self):
|
||||
"""以字典形式返回本对象"""
|
||||
return session_options_to_dict(self)
|
||||
|
||||
def make_session(self):
|
||||
"""根据内在的配置生成Session对象,headers从对象中分离"""
|
||||
s = Session()
|
||||
h = CaseInsensitiveDict(self.headers) if self.headers else CaseInsensitiveDict()
|
||||
|
||||
@ -438,11 +332,6 @@ class SessionOptions(object):
|
||||
return s, h
|
||||
|
||||
def from_session(self, session, headers=None):
|
||||
"""从Session对象中读取配置
|
||||
:param session: Session对象
|
||||
:param headers: headers
|
||||
:return: 当前对象
|
||||
"""
|
||||
self._headers = CaseInsensitiveDict(copy(session.headers).update(headers)) if headers else session.headers
|
||||
self._cookies = session.cookies
|
||||
self._auth = session.auth
|
||||
@ -463,10 +352,6 @@ class SessionOptions(object):
|
||||
|
||||
|
||||
def session_options_to_dict(options):
|
||||
"""把session配置对象转换为字典
|
||||
:param options: session配置对象或字典
|
||||
:return: 配置字典
|
||||
"""
|
||||
if options in (False, None):
|
||||
return SessionOptions(read_file=False).as_dict()
|
||||
|
||||
|
@ -12,125 +12,287 @@ from typing import Any, Union, Tuple, Optional
|
||||
from requests import Session
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.auth import HTTPBasicAuth
|
||||
from requests.cookies import RequestsCookieJar
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
|
||||
class SessionOptions(object):
|
||||
def __init__(self, read_file: [bool, None] = True, ini_path: Union[str, Path] = None):
|
||||
self.ini_path: str = ...
|
||||
self._download_path: str = ...
|
||||
self._headers: dict = ...
|
||||
self._cookies: list = ...
|
||||
self._auth: tuple = ...
|
||||
self._proxies: dict = ...
|
||||
self._hooks: dict = ...
|
||||
self._params: dict = ...
|
||||
self._verify: bool = ...
|
||||
self._cert: Union[str, tuple] = ...
|
||||
self._adapters: list = ...
|
||||
self._stream: bool = ...
|
||||
self._trust_env: bool = ...
|
||||
self._max_redirects: int = ...
|
||||
self._timeout: float = ...
|
||||
self._del_set: set = ...
|
||||
self._retry_times: int = ...
|
||||
self._retry_interval: float = ...
|
||||
"""requests的Session对象配置类"""
|
||||
|
||||
ini_path: Optional[str] = ...
|
||||
_download_path: str = ...
|
||||
_headers: Union[dict, CaseInsensitiveDict, None] = ...
|
||||
_cookies: Union[list, RequestsCookieJar, None] = ...
|
||||
_auth: Optional[tuple] = ...
|
||||
_proxies: Optional[dict] = ...
|
||||
_hooks: Optional[dict] = ...
|
||||
_params: Union[dict, None] = ...
|
||||
_verify: Optional[bool] = ...
|
||||
_cert: Union[str, tuple, None] = ...
|
||||
_adapters: Optional[list] = ...
|
||||
_stream: Optional[bool] = ...
|
||||
_trust_env: Optional[bool] = ...
|
||||
_max_redirects: Optional[int] = ...
|
||||
_timeout: float = ...
|
||||
_del_set: set = ...
|
||||
_retry_times: int = ...
|
||||
_retry_interval: float = ...
|
||||
|
||||
def __init__(self,
|
||||
read_file: [bool, None] = True,
|
||||
ini_path: Union[str, Path] = None):
|
||||
"""
|
||||
:param read_file: 是否从文件读取配置
|
||||
:param ini_path: ini文件路径
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def download_path(self) -> str: ...
|
||||
def download_path(self) -> str:
|
||||
"""返回默认下载路径属性信息"""
|
||||
...
|
||||
|
||||
def set_download_path(self, path: Union[str, Path]) -> SessionOptions: ...
|
||||
def set_download_path(self, path: Union[str, Path]) -> SessionOptions:
|
||||
"""设置默认下载路径
|
||||
:param path: 下载路径
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def timeout(self) -> float: ...
|
||||
def timeout(self) -> float:
|
||||
"""返回timeout属性信息"""
|
||||
...
|
||||
|
||||
def set_timeout(self, second: float) -> SessionOptions: ...
|
||||
def set_timeout(self, second: float) -> SessionOptions:
|
||||
"""设置超时信息
|
||||
:param second: 秒数
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def headers(self) -> dict: ...
|
||||
def proxies(self) -> dict:
|
||||
"""返回proxies设置信息"""
|
||||
...
|
||||
|
||||
def set_headers(self, headers: Union[dict, str, None]) -> SessionOptions: ...
|
||||
|
||||
def set_a_header(self, name: str, value: str) -> SessionOptions: ...
|
||||
|
||||
def remove_a_header(self, name: str) -> SessionOptions: ...
|
||||
|
||||
def clear_headers(self) -> SessionOptions: ...
|
||||
def set_proxies(self, http: Union[str, None], https: Union[str, None] = None) -> SessionOptions:
|
||||
"""设置proxies参数
|
||||
:param http: http代理地址
|
||||
:param https: https代理地址
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def cookies(self) -> list: ...
|
||||
|
||||
def set_cookies(self, cookies: Union[Cookie, CookieJar, list, tuple, str, dict, None]) -> SessionOptions: ...
|
||||
def retry_times(self) -> int:
|
||||
"""返回连接失败时的重试次数"""
|
||||
...
|
||||
|
||||
@property
|
||||
def auth(self) -> Union[Tuple[str, str], HTTPBasicAuth]: ...
|
||||
def retry_interval(self) -> float:
|
||||
"""返回连接失败时的重试间隔(秒)"""
|
||||
...
|
||||
|
||||
def set_auth(self, auth: Union[Tuple[str, str], HTTPBasicAuth, None]) -> SessionOptions: ...
|
||||
def set_retry(self, times: int = None, interval: float = None) -> SessionOptions:
|
||||
"""设置连接失败时的重试操作
|
||||
:param times: 重试次数
|
||||
:param interval: 重试间隔
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def proxies(self) -> dict: ...
|
||||
def headers(self) -> dict:
|
||||
"""返回headers设置信息"""
|
||||
...
|
||||
|
||||
def set_proxies(self, http: Union[str, None], https: Union[str, None] = None) -> SessionOptions: ...
|
||||
def set_headers(self, headers: Union[dict, str, None]) -> SessionOptions:
|
||||
"""设置headers参数
|
||||
:param headers: 参数值,传入None可在ini文件标记删除
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def set_a_header(self, name: str, value: str) -> SessionOptions:
|
||||
"""设置headers中一个项
|
||||
:param name: 设置名称
|
||||
:param value: 设置值
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_a_header(self, name: str) -> SessionOptions:
|
||||
"""从headers中删除一个设置
|
||||
:param name: 要删除的设置
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def clear_headers(self) -> SessionOptions:
|
||||
"""清空已设置的header参数"""
|
||||
...
|
||||
|
||||
@property
|
||||
def retry_times(self) -> int: ...
|
||||
def cookies(self) -> list:
|
||||
"""以list形式返回cookies"""
|
||||
...
|
||||
|
||||
def set_cookies(self, cookies: Union[Cookie, CookieJar, list, tuple, str, dict, None]) -> SessionOptions:
|
||||
"""设置一个或多个cookies信息
|
||||
:param cookies: cookies,可为Cookie, CookieJar, list, tuple, str, dict,传入None可在ini文件标记删除
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def retry_interval(self) -> float: ...
|
||||
def auth(self) -> Union[Tuple[str, str], HTTPBasicAuth]:
|
||||
"""返回认证设置信息"""
|
||||
...
|
||||
|
||||
def set_retry(self, times: int = None, interval: float = None) -> SessionOptions: ...
|
||||
def set_auth(self, auth: Union[Tuple[str, str], HTTPBasicAuth, None]) -> SessionOptions:
|
||||
"""设置认证元组或对象
|
||||
:param auth: 认证元组或对象
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def hooks(self) -> dict: ...
|
||||
def hooks(self) -> dict:
|
||||
"""返回回调方法"""
|
||||
...
|
||||
|
||||
def set_hooks(self, hooks: Union[dict, None]) -> SessionOptions: ...
|
||||
def set_hooks(self, hooks: Union[dict, None]) -> SessionOptions:
|
||||
"""设置回调方法
|
||||
:param hooks: 回调方法
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def params(self) -> dict: ...
|
||||
def params(self) -> dict:
|
||||
"""返回连接参数设置信息"""
|
||||
...
|
||||
|
||||
def set_params(self, params: Union[dict, None]) -> SessionOptions: ...
|
||||
def set_params(self, params: Union[dict, None]) -> SessionOptions:
|
||||
"""设置查询参数字典
|
||||
:param params: 查询参数字典
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def verify(self) -> bool: ...
|
||||
def verify(self) -> bool:
|
||||
"""返回是否验证SSL证书设置"""
|
||||
...
|
||||
|
||||
def set_verify(self, on_off: Union[bool, None]) -> SessionOptions: ...
|
||||
def set_verify(self, on_off: Union[bool, None]) -> SessionOptions:
|
||||
"""设置是否验证SSL证书
|
||||
:param on_off: 是否验证 SSL 证书
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def cert(self) -> Union[str, tuple]: ...
|
||||
def cert(self) -> Union[str, tuple]:
|
||||
"""返回SSL证书设置信息"""
|
||||
...
|
||||
|
||||
def set_cert(self, cert: Union[str, Tuple[str, str], None]) -> SessionOptions: ...
|
||||
def set_cert(self, cert: Union[str, Tuple[str, str], None]) -> SessionOptions:
|
||||
"""SSL客户端证书文件的路径(.pem格式),或(‘cert’, ‘key’)元组
|
||||
:param cert: 证书路径或元组
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def adapters(self): list: ...
|
||||
def adapters(self) -> list:
|
||||
"""返回适配器设置信息"""
|
||||
...
|
||||
|
||||
def add_adapter(self, url: str, adapter: HTTPAdapter) -> SessionOptions: ...
|
||||
def add_adapter(self, url: str, adapter: HTTPAdapter) -> SessionOptions:
|
||||
"""添加适配器
|
||||
:param url: 适配器对应url
|
||||
:param adapter: 适配器对象
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def stream(self) -> bool: ...
|
||||
def stream(self) -> bool:
|
||||
"""返回是否使用流式响应内容设置信息"""
|
||||
...
|
||||
|
||||
def set_stream(self, on_off: Union[bool, None]) -> SessionOptions: ...
|
||||
def set_stream(self, on_off: Union[bool, None]) -> SessionOptions:
|
||||
"""设置是否使用流式响应内容
|
||||
:param on_off: 是否使用流式响应内容
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def trust_env(self) -> bool: ...
|
||||
def trust_env(self) -> bool:
|
||||
"""返回是否信任环境设置信息"""
|
||||
...
|
||||
|
||||
def set_trust_env(self, on_off: Union[bool, None]) -> SessionOptions: ...
|
||||
def set_trust_env(self, on_off: Union[bool, None]) -> SessionOptions:
|
||||
"""设置是否信任环境
|
||||
:param on_off: 是否信任环境
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def max_redirects(self) -> int: ...
|
||||
def max_redirects(self) -> int:
|
||||
"""返回最大重定向次数"""
|
||||
...
|
||||
|
||||
def set_max_redirects(self, times: Union[int, None]) -> SessionOptions: ...
|
||||
def set_max_redirects(self, times: Union[int, None]) -> SessionOptions:
|
||||
"""设置最大重定向次数
|
||||
:param times: 最大重定向次数
|
||||
:return: 返回当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
def _sets(self, arg: str, val: Any) -> None: ...
|
||||
def _sets(self, arg: str, val: Any) -> None:
|
||||
"""给属性赋值或标记删除
|
||||
:param arg: 属性名称
|
||||
:param val: 参数值
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def save(self, path: str = None) -> str: ...
|
||||
def save(self, path: str = None) -> str:
|
||||
"""保存设置到文件
|
||||
:param path: ini文件的路径,传入 'default' 保存到默认ini文件
|
||||
:return: 保存文件的绝对路径
|
||||
"""
|
||||
...
|
||||
|
||||
def save_to_default(self) -> str: ...
|
||||
def save_to_default(self) -> str:
|
||||
"""保存当前配置到默认ini文件"""
|
||||
...
|
||||
|
||||
def as_dict(self) -> dict: ...
|
||||
def as_dict(self) -> dict:
|
||||
"""以字典形式返回本对象"""
|
||||
...
|
||||
|
||||
def make_session(self) -> Tuple[Session, Optional[CaseInsensitiveDict]]: ...
|
||||
def make_session(self) -> Tuple[Session, Optional[CaseInsensitiveDict]]:
|
||||
"""根据内在的配置生成Session对象,headers从对象中分离"""
|
||||
...
|
||||
|
||||
def from_session(self, session: Session, headers: CaseInsensitiveDict = None) -> SessionOptions: ...
|
||||
def from_session(self, session: Session, headers: CaseInsensitiveDict = None) -> SessionOptions:
|
||||
"""从Session对象中读取配置
|
||||
:param session: Session对象
|
||||
:param headers: headers
|
||||
:return: 当前对象
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def session_options_to_dict(options: Union[dict, SessionOptions, None]) -> Union[dict, None]: ...
|
||||
def session_options_to_dict(options: Union[dict, SessionOptions, None]) -> Union[dict, None]:
|
||||
"""把session配置对象转换为字典
|
||||
:param options: session配置对象或字典
|
||||
:return: 配置字典
|
||||
"""
|
||||
...
|
||||
|
@ -566,6 +566,8 @@ class ChromiumElement(DrissionElement):
|
||||
else:
|
||||
self.owner.actions.type(vals)
|
||||
|
||||
return self
|
||||
|
||||
def clear(self, by_js=False):
|
||||
if by_js:
|
||||
self._run_js("this.value='';")
|
||||
@ -574,6 +576,7 @@ class ChromiumElement(DrissionElement):
|
||||
|
||||
self._input_focus()
|
||||
self.input(('\ue009', 'a', '\ue017'), clear=False)
|
||||
return self
|
||||
|
||||
def _input_focus(self):
|
||||
try:
|
||||
@ -586,15 +589,18 @@ class ChromiumElement(DrissionElement):
|
||||
self.owner._run_cdp('DOM.focus', backendNodeId=self._backend_id)
|
||||
except Exception:
|
||||
self._run_js('this.focus();')
|
||||
return self
|
||||
|
||||
def hover(self, offset_x=None, offset_y=None):
|
||||
self.owner.actions.move_to(self, offset_x=offset_x, offset_y=offset_y, duration=.1)
|
||||
return self
|
||||
|
||||
def drag(self, offset_x=0, offset_y=0, duration=.5):
|
||||
curr_x, curr_y = self.rect.midpoint
|
||||
offset_x += curr_x
|
||||
offset_y += curr_y
|
||||
self.drag_to((offset_x, offset_y), duration)
|
||||
return self
|
||||
|
||||
def drag_to(self, ele_or_loc, duration=.5):
|
||||
if isinstance(ele_or_loc, ChromiumElement):
|
||||
@ -602,6 +608,7 @@ class ChromiumElement(DrissionElement):
|
||||
elif not isinstance(ele_or_loc, (list, tuple)):
|
||||
raise TypeError('需要ChromiumElement对象或坐标。')
|
||||
self.owner.actions.hold(self).move_to(ele_or_loc, duration=duration).release()
|
||||
return self
|
||||
|
||||
def _get_obj_id(self, node_id=None, backend_id=None):
|
||||
if node_id:
|
||||
@ -675,6 +682,7 @@ class ChromiumElement(DrissionElement):
|
||||
files = files.split('\n')
|
||||
files = [str(Path(i).absolute()) for i in files]
|
||||
self.owner._run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=self._backend_id)
|
||||
return self
|
||||
|
||||
|
||||
class ShadowRoot(BaseElement):
|
||||
|
@ -526,7 +526,7 @@ class ChromiumElement(DrissionElement):
|
||||
"""
|
||||
...
|
||||
|
||||
def input(self, vals: Any, clear: bool = False, by_js: bool = False) -> None:
|
||||
def input(self, vals: Any, clear: bool = False, by_js: bool = False) -> ChromiumElement:
|
||||
"""输入文本或组合键,也可用于输入文件路径到input元素(路径间用\n间隔)
|
||||
:param vals: 文本值或按键组合
|
||||
:param clear: 输入前是否清空文本框
|
||||
@ -535,7 +535,7 @@ class ChromiumElement(DrissionElement):
|
||||
"""
|
||||
...
|
||||
|
||||
def clear(self, by_js: bool = False) -> None:
|
||||
def clear(self, by_js: bool = False) -> ChromiumElement:
|
||||
"""清空元素文本
|
||||
:param by_js: 是否用js方式清空,为False则用全选+del模拟输入删除
|
||||
:return: None
|
||||
@ -546,11 +546,11 @@ class ChromiumElement(DrissionElement):
|
||||
"""输入前使元素获取焦点"""
|
||||
...
|
||||
|
||||
def focus(self) -> None:
|
||||
def focus(self) -> ChromiumElement:
|
||||
"""使元素获取焦点"""
|
||||
...
|
||||
|
||||
def hover(self, offset_x: int = None, offset_y: int = None) -> None:
|
||||
def hover(self, offset_x: int = None, offset_y: int = None) -> ChromiumElement:
|
||||
"""鼠标悬停,可接受偏移量,偏移量相对于元素左上角坐标。不传入offset_x和offset_y值时悬停在元素中点
|
||||
:param offset_x: 相对元素左上角坐标的x轴偏移量
|
||||
:param offset_y: 相对元素左上角坐标的y轴偏移量
|
||||
@ -558,7 +558,7 @@ class ChromiumElement(DrissionElement):
|
||||
"""
|
||||
...
|
||||
|
||||
def drag(self, offset_x: int = 0, offset_y: int = 0, duration: float = 0.5) -> None:
|
||||
def drag(self, offset_x: int = 0, offset_y: int = 0, duration: float = 0.5) -> ChromiumElement:
|
||||
"""拖拽当前元素到相对位置
|
||||
:param offset_x: x变化值
|
||||
:param offset_y: y变化值
|
||||
@ -567,7 +567,9 @@ class ChromiumElement(DrissionElement):
|
||||
"""
|
||||
...
|
||||
|
||||
def drag_to(self, ele_or_loc: Union[Tuple[int, int], str, ChromiumElement], duration: float = 0.5) -> None:
|
||||
def drag_to(self,
|
||||
ele_or_loc: Union[Tuple[int, int], str, ChromiumElement],
|
||||
duration: float = 0.5) -> ChromiumElement:
|
||||
"""拖拽当前元素,目标为另一个元素或坐标元组(x, y)
|
||||
:param ele_or_loc: 另一个元素或坐标元组,坐标为元素中点的坐标
|
||||
:param duration: 拖动用时,传入0即瞬间到达
|
||||
|
@ -11,11 +11,6 @@ from ..errors import ElementNotFoundError
|
||||
|
||||
class NoneElement(object):
|
||||
def __init__(self, page=None, method=None, args=None):
|
||||
"""
|
||||
:param page: 元素所在页面
|
||||
:param method: 查找元素的方法
|
||||
:param args: 查找元素的参数
|
||||
"""
|
||||
if method and Settings.raise_when_ele_not_found: # 无传入method时不自动抛出,由调用者处理
|
||||
raise ElementNotFoundError(None, method=method, arguments=args)
|
||||
|
||||
@ -49,11 +44,10 @@ class NoneElement(object):
|
||||
raise ElementNotFoundError(None, self.method, self.args)
|
||||
|
||||
def __eq__(self, other):
|
||||
if other is None:
|
||||
return True
|
||||
return other is None
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return 'None'
|
||||
return f'<NoneElement method={self.method}, {", ".join([f"{k}={v}" for k, v in self.args.items()])}>'
|
||||
|
32
DrissionPage/_elements/none_element.pyi
Normal file
32
DrissionPage/_elements/none_element.pyi
Normal file
@ -0,0 +1,32 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
|
||||
@License : BSD 3-Clause.
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from .._base.base import BasePage
|
||||
|
||||
|
||||
class NoneElement(object):
|
||||
def __init__(self, page: BasePage = None,
|
||||
method: str = None,
|
||||
args: dict = None):
|
||||
"""
|
||||
:param page: 元素所在页面
|
||||
:param method: 查找元素的方法
|
||||
:param args: 查找元素的参数
|
||||
"""
|
||||
...
|
||||
|
||||
def __call__(self, *args, **kwargs) -> NoneElement: ...
|
||||
|
||||
def __getattr__(self, item: str) -> str: ...
|
||||
|
||||
def __eq__(self, other: Any) -> bool: ...
|
||||
|
||||
def __bool__(self) -> bool: ...
|
||||
|
||||
def __repr__(self) -> str: ...
|
@ -21,10 +21,6 @@ from ..errors import BrowserConnectError
|
||||
|
||||
|
||||
def connect_browser(option):
|
||||
"""连接或启动浏览器
|
||||
:param option: ChromiumOptions对象
|
||||
:return: 返回是否接管的浏览器
|
||||
"""
|
||||
address = option.address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
|
||||
browser_path = option.browser_path
|
||||
|
||||
@ -67,10 +63,6 @@ def connect_browser(option):
|
||||
|
||||
|
||||
def get_launch_args(opt):
|
||||
"""从ChromiumOptions获取命令行启动参数
|
||||
:param opt: ChromiumOptions
|
||||
:return: 启动参数列表
|
||||
"""
|
||||
# ----------处理arguments-----------
|
||||
result = set()
|
||||
user_path = False
|
||||
@ -107,10 +99,6 @@ def get_launch_args(opt):
|
||||
|
||||
|
||||
def set_prefs(opt):
|
||||
"""处理启动配置中的prefs项,目前只能对已存在文件夹配置
|
||||
:param opt: ChromiumOptions
|
||||
:return: None
|
||||
"""
|
||||
if not opt.user_data_path or (not opt.preferences and not opt._prefs_to_del):
|
||||
return
|
||||
prefs = opt.preferences
|
||||
@ -149,10 +137,6 @@ def set_prefs(opt):
|
||||
|
||||
|
||||
def set_flags(opt):
|
||||
"""处理启动配置中的flags项
|
||||
:param opt: ChromiumOptions
|
||||
:return: None
|
||||
"""
|
||||
if not opt.user_data_path or (not opt.clear_file_flags and not opt.flags):
|
||||
return
|
||||
|
||||
@ -185,12 +169,6 @@ def set_flags(opt):
|
||||
|
||||
|
||||
def test_connect(ip, port, timeout=30):
|
||||
"""测试浏览器是否可用
|
||||
:param ip: 浏览器ip
|
||||
:param port: 浏览器端口
|
||||
:param timeout: 超时时间(秒)
|
||||
:return: None
|
||||
"""
|
||||
end_time = perf_counter() + timeout
|
||||
s = Session()
|
||||
s.trust_env = False
|
||||
@ -276,7 +254,6 @@ def _remove_arg_from_dict(target_dict: dict, arg: str) -> None:
|
||||
|
||||
|
||||
def get_chrome_path(ini_path):
|
||||
"""从ini文件或系统变量中获取chrome可执行文件的路径"""
|
||||
# -----------从ini文件中获取--------------
|
||||
if ini_path and Path(ini_path).exists():
|
||||
path = OptionsManager(ini_path).chromium_options.get('browser_path', None)
|
||||
|
@ -10,19 +10,51 @@ from typing import Union
|
||||
from .._configs.chromium_options import ChromiumOptions
|
||||
|
||||
|
||||
def connect_browser(option: ChromiumOptions) -> bool: ...
|
||||
def connect_browser(option: ChromiumOptions) -> bool:
|
||||
"""连接或启动浏览器
|
||||
:param option: ChromiumOptions对象
|
||||
:return: 返回是否接管的浏览器
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def get_launch_args(opt: ChromiumOptions) -> list: ...
|
||||
def get_launch_args(opt: ChromiumOptions) -> list:
|
||||
"""从ChromiumOptions获取命令行启动参数
|
||||
:param opt: ChromiumOptions
|
||||
:return: 启动参数列表
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def set_prefs(opt: ChromiumOptions) -> None: ...
|
||||
def set_prefs(opt: ChromiumOptions) -> None:
|
||||
"""处理启动配置中的prefs项,目前只能对已存在文件夹配置
|
||||
:param opt: ChromiumOptions
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def set_flags(opt: ChromiumOptions) -> None: ...
|
||||
def set_flags(opt: ChromiumOptions) -> None:
|
||||
"""处理启动配置中的flags项
|
||||
:param opt: ChromiumOptions
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def test_connect(ip: str, port: Union[int, str], timeout: float = 30) -> bool: ...
|
||||
def test_connect(ip: str, port: Union[int, str], timeout: float = 30) -> bool:
|
||||
"""测试浏览器是否可用
|
||||
:param ip: 浏览器ip
|
||||
:param port: 浏览器端口
|
||||
:param timeout: 超时时间(秒)
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def get_chrome_path(ini_path: str) -> Union[str, None]: ...
|
||||
def get_chrome_path(ini_path: str) -> Union[str, None]:
|
||||
"""从ini文件或系统变量中获取chrome可执行文件的路径
|
||||
:param ini_path: ini文件路径
|
||||
:return: 文件路径
|
||||
"""
|
||||
...
|
||||
|
@ -12,10 +12,6 @@ from tldextract import extract
|
||||
|
||||
|
||||
def cookie_to_dict(cookie):
|
||||
"""把Cookie对象转为dict格式
|
||||
:param cookie: Cookie对象、字符串或字典
|
||||
:return: cookie字典
|
||||
"""
|
||||
if isinstance(cookie, Cookie):
|
||||
cookie_dict = cookie.__dict__.copy()
|
||||
cookie_dict.pop('rfc2109', None)
|
||||
@ -44,10 +40,6 @@ def cookie_to_dict(cookie):
|
||||
|
||||
|
||||
def cookies_to_tuple(cookies):
|
||||
"""把cookies转为tuple格式
|
||||
:param cookies: cookies信息,可为CookieJar, list, tuple, str, dict
|
||||
:return: 返回tuple形式的cookies
|
||||
"""
|
||||
if isinstance(cookies, (list, tuple, CookieJar)):
|
||||
cookies = tuple(cookie_to_dict(cookie) for cookie in cookies)
|
||||
|
||||
@ -74,11 +66,6 @@ def cookies_to_tuple(cookies):
|
||||
|
||||
|
||||
def set_session_cookies(session, cookies):
|
||||
"""设置Session对象的cookies
|
||||
:param session: Session对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
for cookie in cookies_to_tuple(cookies):
|
||||
if cookie['value'] is None:
|
||||
cookie['value'] = ''
|
||||
@ -94,11 +81,6 @@ def set_session_cookies(session, cookies):
|
||||
|
||||
|
||||
def set_browser_cookies(browser, cookies):
|
||||
"""设置cookies值
|
||||
:param browser: 页面对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
c = []
|
||||
for cookie in cookies_to_tuple(cookies):
|
||||
if 'domain' not in cookie and 'url' not in cookie:
|
||||
@ -108,11 +90,6 @@ def set_browser_cookies(browser, cookies):
|
||||
|
||||
|
||||
def set_tab_cookies(page, cookies):
|
||||
"""设置cookies值
|
||||
:param page: 页面对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
for cookie in cookies_to_tuple(cookies):
|
||||
cookie = format_cookie(cookie)
|
||||
|
||||
@ -154,11 +131,6 @@ def set_tab_cookies(page, cookies):
|
||||
|
||||
|
||||
def is_cookie_in_driver(page, cookie):
|
||||
"""查询cookie是否在浏览器内
|
||||
:param page: BasePage对象
|
||||
:param cookie: dict格式cookie
|
||||
:return: bool
|
||||
"""
|
||||
if 'domain' in cookie:
|
||||
for c in page.cookies(all_domains=True):
|
||||
if cookie['name'] == c['name'] and cookie['value'] == c['value'] and cookie['domain'] == c.get('domain',
|
||||
@ -172,10 +144,6 @@ def is_cookie_in_driver(page, cookie):
|
||||
|
||||
|
||||
def format_cookie(cookie):
|
||||
"""设置cookie为可用格式
|
||||
:param cookie: dict格式cookie
|
||||
:return: 格式化后的cookie字典
|
||||
"""
|
||||
if 'expiry' in cookie:
|
||||
cookie['expires'] = int(cookie['expiry'])
|
||||
cookie.pop('expiry')
|
||||
@ -235,15 +203,12 @@ def format_cookie(cookie):
|
||||
|
||||
class CookiesList(list):
|
||||
def as_dict(self):
|
||||
"""以dict格式返回,只包含name和value字段"""
|
||||
return {c['name']: c['value'] for c in self}
|
||||
|
||||
def as_str(self):
|
||||
"""以str格式返回,只包含name和value字段"""
|
||||
return '; '.join([f'{c["name"]}={c["value"]}' for c in self])
|
||||
|
||||
def as_json(self):
|
||||
"""以json格式返回"""
|
||||
from json import dumps
|
||||
return dumps(self)
|
||||
|
||||
|
@ -15,32 +15,80 @@ from .._base.browser import Chromium
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
|
||||
|
||||
def cookie_to_dict(cookie: Union[Cookie, str, dict]) -> dict: ...
|
||||
def cookie_to_dict(cookie: Union[Cookie, str, dict]) -> dict:
|
||||
"""把Cookie对象转为dict格式
|
||||
:param cookie: Cookie对象、字符串或字典
|
||||
:return: cookie字典
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def cookies_to_tuple(cookies: Union[RequestsCookieJar, list, tuple, str, dict, Cookie]) -> tuple: ...
|
||||
def cookies_to_tuple(cookies: Union[RequestsCookieJar, list, tuple, str, dict, Cookie]) -> tuple:
|
||||
"""把cookies转为tuple格式
|
||||
:param cookies: cookies信息,可为CookieJar, list, tuple, str, dict
|
||||
:return: 返回tuple形式的cookies
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def set_session_cookies(session: Session, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...
|
||||
def set_session_cookies(session: Session,
|
||||
cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None:
|
||||
"""设置Session对象的cookies
|
||||
:param session: Session对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def set_browser_cookies(browser: Chromium, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...
|
||||
def set_browser_cookies(browser: Chromium,
|
||||
cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None:
|
||||
"""设置cookies值
|
||||
:param browser: 页面对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def set_tab_cookies(page: ChromiumBase, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...
|
||||
def set_tab_cookies(page: ChromiumBase,
|
||||
cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None:
|
||||
"""设置cookies值
|
||||
:param page: 页面对象
|
||||
:param cookies: cookies信息
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def is_cookie_in_driver(page: ChromiumBase, cookie: dict) -> bool: ...
|
||||
def is_cookie_in_driver(page: ChromiumBase, cookie: dict) -> bool:
|
||||
"""查询cookie是否在浏览器内
|
||||
:param page: BasePage对象
|
||||
:param cookie: dict格式cookie
|
||||
:return: bool
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def format_cookie(cookie: dict) -> dict: ...
|
||||
def format_cookie(cookie: dict) -> dict:
|
||||
"""设置cookie为可用格式
|
||||
:param cookie: dict格式cookie
|
||||
:return: 格式化后的cookie字典
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class CookiesList(list):
|
||||
def as_dict(self) -> dict: ...
|
||||
def as_dict(self) -> dict:
|
||||
"""以dict格式返回,只包含name和value字段"""
|
||||
...
|
||||
|
||||
def as_str(self) -> str: ...
|
||||
def as_str(self) -> str:
|
||||
"""以str格式返回,只包含name和value字段"""
|
||||
...
|
||||
|
||||
def as_json(self) -> str: ...
|
||||
def as_json(self) -> str:
|
||||
"""以json格式返回"""
|
||||
...
|
||||
|
||||
def __next__(self) -> dict: ...
|
||||
|
@ -12,9 +12,9 @@ from .._elements.none_element import NoneElement
|
||||
|
||||
|
||||
class SessionElementsList(list):
|
||||
def __init__(self, page=None, *args):
|
||||
def __init__(self, owner=None, *args):
|
||||
super().__init__(*args)
|
||||
self._page = page
|
||||
self._owner = owner
|
||||
|
||||
@property
|
||||
def get(self):
|
||||
@ -56,17 +56,6 @@ class ChromiumElementsList(SessionElementsList):
|
||||
|
||||
def search_one(self, index=1, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
|
||||
have_rect=None, have_text=None):
|
||||
"""或关系筛选元素,获取一个结果
|
||||
:param index: 元素序号,从1开始
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return _search_one(self, index=index, displayed=displayed, checked=checked, selected=selected,
|
||||
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text)
|
||||
|
||||
@ -77,29 +66,13 @@ class SessionFilterOne(object):
|
||||
self._index = 1
|
||||
|
||||
def __call__(self, index=1):
|
||||
"""返回结果中第几个元素
|
||||
:param index: 元素序号,从1开始
|
||||
:return: 对象自身
|
||||
"""
|
||||
self._index = index
|
||||
return self
|
||||
|
||||
def attr(self, name, value, equal=True):
|
||||
"""以是否拥有某个attribute值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._get_attr(name, value, 'attr', equal=equal)
|
||||
|
||||
def text(self, text, fuzzy=True, contain=True):
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
num = 0
|
||||
if contain:
|
||||
for i in self._list:
|
||||
@ -115,16 +88,10 @@ class SessionFilterOne(object):
|
||||
num += 1
|
||||
if self._index == num:
|
||||
return i
|
||||
return NoneElement(self._list._page, 'text()',
|
||||
return NoneElement(self._list._owner, 'text()',
|
||||
args={'text': text, 'fuzzy': fuzzy, 'contain': contain, 'index': self._index})
|
||||
|
||||
def _get_attr(self, name, value, method, equal=True):
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
num = 0
|
||||
if equal:
|
||||
for i in self._list:
|
||||
@ -138,7 +105,7 @@ class SessionFilterOne(object):
|
||||
num += 1
|
||||
if self._index == num:
|
||||
return i
|
||||
return NoneElement(self._list._page, f'{method}()',
|
||||
return NoneElement(self._list._owner, f'{method}()',
|
||||
args={'name': name, 'value': value, 'equal': equal, 'index': self._index})
|
||||
|
||||
|
||||
@ -158,28 +125,15 @@ class SessionFilter(SessionFilterOne):
|
||||
|
||||
@property
|
||||
def get(self):
|
||||
"""返回用于获取元素属性的对象"""
|
||||
return self._list.get
|
||||
|
||||
def text(self, text, fuzzy=True, contain=True):
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
self._list = _text_all(self._list, SessionElementsList(page=self._list._page),
|
||||
self._list = _text_all(self._list, SessionElementsList(owner=self._list._owner),
|
||||
text=text, fuzzy=fuzzy, contain=contain)
|
||||
return self
|
||||
|
||||
def _get_attr(self, name, value, method, equal=True):
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
self._list = _get_attr_all(self._list, SessionElementsList(page=self._list._page),
|
||||
self._list = _get_attr_all(self._list, SessionElementsList(owner=self._list._owner),
|
||||
name=name, value=value, method=method, equal=equal)
|
||||
return self
|
||||
|
||||
@ -187,71 +141,30 @@ class SessionFilter(SessionFilterOne):
|
||||
class ChromiumFilterOne(SessionFilterOne):
|
||||
|
||||
def displayed(self, equal=True):
|
||||
"""以是否显示为条件筛选元素
|
||||
:param equal: 是否匹配显示的元素,False匹配不显示的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('is_displayed', equal=equal)
|
||||
|
||||
def checked(self, equal=True):
|
||||
"""以是否被选中为条件筛选元素
|
||||
:param equal: 是否匹配被选中的元素,False匹配不被选中的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('is_checked', equal=equal)
|
||||
|
||||
def selected(self, equal=True):
|
||||
"""以是否被选择为条件筛选元素,用于<select>元素项目
|
||||
:param equal: 是否匹配被选择的元素,False匹配不被选择的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('is_selected', equal=equal)
|
||||
|
||||
def enabled(self, equal=True):
|
||||
"""以是否可用为条件筛选元素
|
||||
:param equal: 是否匹配可用的元素,False表示匹配disabled状态的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('is_enabled', equal=equal)
|
||||
|
||||
def clickable(self, equal=True):
|
||||
"""以是否可点击为条件筛选元素
|
||||
:param equal: 是否匹配可点击的元素,False表示匹配不是可点击的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('is_clickable', equal=equal)
|
||||
|
||||
def have_rect(self, equal=True):
|
||||
"""以是否有大小为条件筛选元素
|
||||
:param equal: 是否匹配有大小的元素,False表示匹配没有大小的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._any_state('has_rect', equal=equal)
|
||||
|
||||
def style(self, name, value, equal=True):
|
||||
"""以是否拥有某个style值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._get_attr(name, value, 'style', equal=equal)
|
||||
|
||||
def property(self, name, value, equal=True):
|
||||
"""以是否拥有某个property值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return self._get_attr(name, value, 'property', equal=equal)
|
||||
|
||||
def _any_state(self, name, equal=True):
|
||||
"""
|
||||
:param name: 状态名称
|
||||
:param equal: 是否是指定状态,False表示否定状态
|
||||
:return: 选中的元素
|
||||
"""
|
||||
num = 0
|
||||
if equal:
|
||||
for i in self._list:
|
||||
@ -265,7 +178,7 @@ class ChromiumFilterOne(SessionFilterOne):
|
||||
num += 1
|
||||
if self._index == num:
|
||||
return i
|
||||
return NoneElement(self._list._page, f'{name}()', args={'equal': equal, 'index': self._index})
|
||||
return NoneElement(self._list._owner, f'{name}()', args={'equal': equal, 'index': self._index})
|
||||
|
||||
|
||||
class ChromiumFilter(ChromiumFilterOne):
|
||||
@ -284,69 +197,30 @@ class ChromiumFilter(ChromiumFilterOne):
|
||||
|
||||
@property
|
||||
def get(self):
|
||||
"""返回用于获取元素属性的对象"""
|
||||
return self._list.get
|
||||
|
||||
def search_one(self, index=1, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
|
||||
have_rect=None, have_text=None):
|
||||
"""或关系筛选元素,获取一个结果
|
||||
:param index: 元素序号,从1开始
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return _search_one(self._list, index=index, displayed=displayed, checked=checked, selected=selected,
|
||||
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text)
|
||||
|
||||
def search(self, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
|
||||
have_rect=None, have_text=None):
|
||||
"""或关系筛选元素
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
return _search(self._list, displayed=displayed, checked=checked, selected=selected, enabled=enabled,
|
||||
clickable=clickable, have_rect=have_rect, have_text=have_text)
|
||||
|
||||
def text(self, text, fuzzy=True, contain=True):
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
self._list = _text_all(self._list, ChromiumElementsList(page=self._list._page),
|
||||
self._list = _text_all(self._list, ChromiumElementsList(owner=self._list._owner),
|
||||
text=text, fuzzy=fuzzy, contain=contain)
|
||||
return self
|
||||
|
||||
def _get_attr(self, name, value, method, equal=True):
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
self._list = _get_attr_all(self._list, ChromiumElementsList(page=self._list._page),
|
||||
self._list = _get_attr_all(self._list, ChromiumElementsList(owner=self._list._owner),
|
||||
name=name, value=value, method=method, equal=equal)
|
||||
return self
|
||||
|
||||
def _any_state(self, name, equal=True):
|
||||
"""
|
||||
:param name: 状态名称
|
||||
:param equal: 是否是指定状态,False表示否定状态
|
||||
:return: 选中的列表
|
||||
"""
|
||||
r = ChromiumElementsList(page=self._list._page)
|
||||
r = ChromiumElementsList(owner=self._list._owner)
|
||||
if equal:
|
||||
for i in self._list:
|
||||
if not isinstance(i, str) and getattr(i.states, name):
|
||||
@ -364,30 +238,16 @@ class Getter(object):
|
||||
self._list = _list
|
||||
|
||||
def links(self):
|
||||
"""返回所有元素的link属性组成的列表"""
|
||||
return [e.link for e in self._list if not isinstance(e, str)]
|
||||
|
||||
def texts(self):
|
||||
"""返回所有元素的text属性组成的列表"""
|
||||
return [e if isinstance(e, str) else e.text for e in self._list]
|
||||
|
||||
def attrs(self, name):
|
||||
"""返回所有元素指定的attr属性组成的列表
|
||||
:param name: 属性名称
|
||||
:return: 属性文本组成的列表
|
||||
"""
|
||||
return [e.attr(name) for e in self._list if not isinstance(e, str)]
|
||||
|
||||
|
||||
def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10):
|
||||
"""传入多个定位符,获取多个ele
|
||||
:param locators: 定位符组成的列表
|
||||
:param owner: 页面或元素对象
|
||||
:param any_one: 是否找到任何一个即返回
|
||||
:param first_ele: 每个定位符是否只获取第一个元素
|
||||
:param timeout: 超时时间(秒)
|
||||
:return: 多个定位符组成的dict
|
||||
"""
|
||||
res = {loc: False for loc in locators}
|
||||
end_time = perf_counter() + timeout
|
||||
while perf_counter() <= end_time:
|
||||
@ -405,12 +265,6 @@ def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10):
|
||||
|
||||
|
||||
def get_frame(owner, loc_ind_ele, timeout=None):
|
||||
"""获取页面中一个frame对象
|
||||
:param owner: 要在其中查找元素的对象
|
||||
:param loc_ind_ele: 定位符、iframe序号、ChromiumFrame对象,序号从1开始,可传入负数获取倒数第几个
|
||||
:param timeout: 查找元素超时时间(秒)
|
||||
:return: ChromiumFrame对象
|
||||
"""
|
||||
if isinstance(loc_ind_ele, str):
|
||||
if not is_loc(loc_ind_ele):
|
||||
xpath = f'xpath://*[(name()="iframe" or name()="frame") and ' \
|
||||
@ -492,7 +346,7 @@ def _search(_list, displayed=None, checked=None, selected=None, enabled=None, cl
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
r = ChromiumElementsList(page=_list._page)
|
||||
r = ChromiumElementsList(owner=_list._owner)
|
||||
for i in _list:
|
||||
if not isinstance(i, str) and (
|
||||
(displayed is not None and (displayed is True and i.states.is_displayed)
|
||||
@ -547,7 +401,7 @@ def _search_one(_list, index=1, displayed=None, checked=None, selected=None, ena
|
||||
if num == index:
|
||||
return i
|
||||
|
||||
return NoneElement(_list._page, method='filter()', args={'displayed': displayed,
|
||||
return NoneElement(_list._owner, method='filter()', args={'displayed': displayed,
|
||||
'checked': checked, 'selected': selected,
|
||||
'enabled': enabled, 'clickable': clickable,
|
||||
'have_rect': have_rect, 'have_text': have_text})
|
||||
|
@ -10,45 +10,52 @@ from typing import Union, List, Optional, Iterable
|
||||
from .._base.base import BaseParser
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
from .._elements.session_element import SessionElement
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
from .._pages.chromium_frame import ChromiumFrame
|
||||
|
||||
|
||||
def get_eles(locators: Union[List[str], tuple],
|
||||
owner: BaseParser,
|
||||
any_one: bool = False,
|
||||
first_ele: bool = True,
|
||||
timeout: float = 10) -> dict: ...
|
||||
|
||||
|
||||
def get_frame(owner: BaseParser,
|
||||
loc_ind_ele: Union[str, int, tuple, ChromiumFrame, ChromiumElement],
|
||||
timeout: float = None) -> ChromiumFrame: ...
|
||||
from .._pages.session_page import SessionPage
|
||||
|
||||
|
||||
class SessionElementsList(list):
|
||||
_page = ...
|
||||
_owner: SessionPage = ...
|
||||
|
||||
def __init__(self, page=None, *args): ...
|
||||
def __init__(self,
|
||||
owner: SessionPage = None,
|
||||
*args): ...
|
||||
|
||||
@property
|
||||
def get(self) -> Getter: ...
|
||||
def get(self) -> Getter:
|
||||
"""返回用于属性的对象"""
|
||||
...
|
||||
|
||||
@property
|
||||
def filter(self) -> SessionFilter: ...
|
||||
def filter(self) -> SessionFilter:
|
||||
"""返回用于筛选多个元素的对象"""
|
||||
...
|
||||
|
||||
@property
|
||||
def filter_one(self) -> SessionFilterOne: ...
|
||||
def filter_one(self) -> SessionFilterOne:
|
||||
"""用于筛选单个元素的对象"""
|
||||
...
|
||||
|
||||
def __next__(self) -> SessionElement: ...
|
||||
|
||||
|
||||
class ChromiumElementsList(SessionElementsList):
|
||||
_owner: ChromiumBase = ...
|
||||
|
||||
def __init__(self,
|
||||
owner: ChromiumBase = None,
|
||||
*args): ...
|
||||
|
||||
@property
|
||||
def filter(self) -> ChromiumFilter: ...
|
||||
def filter(self) -> ChromiumFilter:
|
||||
"""返回用于筛选多个元素的对象"""
|
||||
...
|
||||
|
||||
@property
|
||||
def filter_one(self) -> ChromiumFilterOne: ...
|
||||
def filter_one(self) -> ChromiumFilterOne:
|
||||
"""用于筛选单个元素的对象"""
|
||||
...
|
||||
|
||||
def search(self,
|
||||
displayed: Optional[bool] = None,
|
||||
@ -57,7 +64,18 @@ class ChromiumElementsList(SessionElementsList):
|
||||
enabled: Optional[bool] = None,
|
||||
clickable: Optional[bool] = None,
|
||||
have_rect: Optional[bool] = None,
|
||||
have_text: Optional[bool] = None) -> ChromiumFilter: ...
|
||||
have_text: Optional[bool] = None) -> ChromiumFilter:
|
||||
"""或关系筛选元素
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def search_one(self,
|
||||
index: int = 1,
|
||||
@ -67,7 +85,19 @@ class ChromiumElementsList(SessionElementsList):
|
||||
enabled: Optional[bool] = None,
|
||||
clickable: Optional[bool] = None,
|
||||
have_rect: Optional[bool] = None,
|
||||
have_text: Optional[bool] = None) -> ChromiumElement: ...
|
||||
have_text: Optional[bool] = None) -> ChromiumElement:
|
||||
"""或关系筛选元素,获取一个结果
|
||||
:param index: 元素序号,从1开始
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def __next__(self) -> ChromiumElement: ...
|
||||
|
||||
@ -76,19 +106,49 @@ class SessionFilterOne(object):
|
||||
_list: SessionElementsList = ...
|
||||
_index: int = ...
|
||||
|
||||
def __init__(self, _list: SessionElementsList, index: int = 1): ...
|
||||
def __init__(self, _list: SessionElementsList):
|
||||
"""
|
||||
:param _list: 元素列表对象
|
||||
"""
|
||||
...
|
||||
|
||||
def __call__(self, index: int = 1) -> SessionFilterOne: ...
|
||||
def __call__(self, index: int = 1) -> SessionFilterOne:
|
||||
"""返回结果中第几个元素
|
||||
:param index: 元素序号,从1开始
|
||||
:return: 对象自身
|
||||
"""
|
||||
...
|
||||
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> SessionElement: ...
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> SessionElement:
|
||||
"""以是否拥有某个attribute值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> SessionElement: ...
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> SessionElement:
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _get_attr(self,
|
||||
name: str,
|
||||
value: str,
|
||||
method: str,
|
||||
equal: bool = True) -> SessionElement: ...
|
||||
equal: bool = True) -> SessionElement:
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class SessionFilter(SessionFilterOne):
|
||||
@ -102,54 +162,160 @@ class SessionFilter(SessionFilterOne):
|
||||
def __getitem__(self, item: int) -> SessionElement: ...
|
||||
|
||||
@property
|
||||
def get(self) -> Getter: ...
|
||||
def get(self) -> Getter:
|
||||
"""返回用于获取元素属性的对象"""
|
||||
...
|
||||
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> SessionFilter: ...
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> SessionFilter:
|
||||
"""以是否拥有某个attribute值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> SessionFilter: ...
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> SessionFilter:
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _get_attr(self,
|
||||
name: str,
|
||||
value: str,
|
||||
method: str,
|
||||
equal: bool = True) -> SessionFilter: ...
|
||||
equal: bool = True) -> SessionFilter:
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class ChromiumFilterOne(SessionFilterOne):
|
||||
_list: ChromiumElementsList = ...
|
||||
|
||||
def __init__(self, _list: ChromiumElementsList): ...
|
||||
def __init__(self, _list: ChromiumElementsList):
|
||||
"""
|
||||
:param _list: 元素列表对象
|
||||
"""
|
||||
...
|
||||
|
||||
def __call__(self, index: int = 1) -> ChromiumFilterOne: ...
|
||||
def __call__(self, index: int = 1) -> ChromiumFilterOne:
|
||||
"""返回结果中第几个元素
|
||||
:param index: 元素序号,从1开始
|
||||
:return: 对象自身
|
||||
"""
|
||||
...
|
||||
|
||||
def displayed(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def displayed(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否显示为条件筛选元素
|
||||
:param equal: 是否匹配显示的元素,False匹配不显示的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def checked(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def checked(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否被选中为条件筛选元素
|
||||
:param equal: 是否匹配被选中的元素,False匹配不被选中的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def selected(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def selected(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否被选择为条件筛选元素,用于<select>元素项目
|
||||
:param equal: 是否匹配被选择的元素,False匹配不被选择的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def enabled(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def enabled(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否可用为条件筛选元素
|
||||
:param equal: 是否匹配可用的元素,False表示匹配disabled状态的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def clickable(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def clickable(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否可点击为条件筛选元素
|
||||
:param equal: 是否匹配可点击的元素,False表示匹配不是可点击的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def have_rect(self, equal: bool = True) -> ChromiumElement: ...
|
||||
def have_rect(self, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否有大小为条件筛选元素
|
||||
:param equal: 是否匹配有大小的元素,False表示匹配没有大小的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def style(self, name: str, value: str, equal: bool = True) -> ChromiumElement: ...
|
||||
def style(self, name: str, value: str, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否拥有某个style值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def property(self,
|
||||
name: str,
|
||||
value: str, equal: bool = True) -> ChromiumElement: ...
|
||||
value: str, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否拥有某个property值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumElement: ...
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumElement:
|
||||
"""以是否拥有某个attribute值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> ChromiumElement: ...
|
||||
def text(self,
|
||||
text: str,
|
||||
fuzzy: bool = True,
|
||||
contain: bool = True) -> ChromiumElement:
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _get_attr(self,
|
||||
name: str,
|
||||
value: str,
|
||||
method: str, equal: bool = True) -> ChromiumElement: ...
|
||||
method: str, equal: bool = True) -> ChromiumElement:
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _any_state(self, name: str, equal: bool = True) -> ChromiumElement: ...
|
||||
def _any_state(self, name: str, equal: bool = True) -> ChromiumElement:
|
||||
"""
|
||||
:param name: 状态名称
|
||||
:param equal: 是否是指定状态,False表示否定状态
|
||||
:return: 选中的列表
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class ChromiumFilter(ChromiumFilterOne):
|
||||
@ -163,38 +329,80 @@ class ChromiumFilter(ChromiumFilterOne):
|
||||
def __getitem__(self, item: int) -> ChromiumElement: ...
|
||||
|
||||
@property
|
||||
def get(self) -> Getter: ...
|
||||
def get(self) -> Getter:
|
||||
"""返回用于获取元素属性的对象"""
|
||||
...
|
||||
|
||||
def displayed(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def displayed(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否显示为条件筛选元素
|
||||
:param equal: 是否匹配显示的元素,False匹配不显示的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def checked(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def checked(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否被选中为条件筛选元素
|
||||
:param equal: 是否匹配被选中的元素,False匹配不被选中的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def selected(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def selected(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否被选择为条件筛选元素,用于<select>元素项目
|
||||
:param equal: 是否匹配被选择的元素,False匹配不被选择的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def enabled(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def enabled(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否可用为条件筛选元素
|
||||
:param equal: 是否匹配可用的元素,False表示匹配disabled状态的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def clickable(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def clickable(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否可点击为条件筛选元素
|
||||
:param equal: 是否匹配可点击的元素,False表示匹配不是可点击的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def have_rect(self, equal: bool = True) -> ChromiumFilter: ...
|
||||
def have_rect(self, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否有大小为条件筛选元素
|
||||
:param equal: 是否匹配有大小的元素,False表示匹配没有大小的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def style(self, name: str, value: str, equal: bool = True) -> ChromiumFilter: ...
|
||||
def style(self, name: str, value: str, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否拥有某个style值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def property(self,
|
||||
name: str,
|
||||
value: str, equal: bool = True) -> ChromiumFilter: ...
|
||||
value: str, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否拥有某个property值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumFilter: ...
|
||||
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> ChromiumFilter: ...
|
||||
|
||||
def search(self,
|
||||
displayed: Optional[bool] = None,
|
||||
checked: Optional[bool] = None,
|
||||
selected: Optional[bool] = None,
|
||||
enabled: Optional[bool] = None,
|
||||
clickable: Optional[bool] = None,
|
||||
have_rect: Optional[bool] = None,
|
||||
have_text: Optional[bool] = None) -> ChromiumFilter: ...
|
||||
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumFilter:
|
||||
"""以是否拥有某个attribute值为条件筛选元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param equal: True表示匹配name值为value值的元素,False表示匹配name值不为value值的
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def search_one(self,
|
||||
index: int = 1,
|
||||
@ -204,23 +412,118 @@ class ChromiumFilter(ChromiumFilterOne):
|
||||
enabled: Optional[bool] = None,
|
||||
clickable: Optional[bool] = None,
|
||||
have_rect: Optional[bool] = None,
|
||||
have_text: Optional[bool] = None) -> ChromiumElement: ...
|
||||
have_text: Optional[bool] = None) -> ChromiumElement:
|
||||
"""或关系筛选元素,获取一个结果
|
||||
:param index: 元素序号,从1开始
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def search(self,
|
||||
displayed: Optional[bool] = None,
|
||||
checked: Optional[bool] = None,
|
||||
selected: Optional[bool] = None,
|
||||
enabled: Optional[bool] = None,
|
||||
clickable: Optional[bool] = None,
|
||||
have_rect: Optional[bool] = None,
|
||||
have_text: Optional[bool] = None) -> ChromiumFilter:
|
||||
"""或关系筛选元素
|
||||
:param displayed: 是否显示,bool,None为忽略该项
|
||||
:param checked: 是否被选中,bool,None为忽略该项
|
||||
:param selected: 是否被选择,bool,None为忽略该项
|
||||
:param enabled: 是否可用,bool,None为忽略该项
|
||||
:param clickable: 是否可点击,bool,None为忽略该项
|
||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> ChromiumFilter:
|
||||
"""以是否含有指定文本为条件筛选元素
|
||||
:param text: 用于匹配的文本
|
||||
:param fuzzy: 是否模糊匹配
|
||||
:param contain: 是否包含该字符串,False表示不包含
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _get_attr(self,
|
||||
name: str,
|
||||
value: str,
|
||||
method: str, equal: bool = True) -> ChromiumFilter: ...
|
||||
method: str, equal: bool = True) -> ChromiumFilter:
|
||||
"""返回通过某个方法可获得某个值的元素
|
||||
:param name: 属性名称
|
||||
:param value: 属性值
|
||||
:param method: 方法名称
|
||||
:return: 筛选结果
|
||||
"""
|
||||
...
|
||||
|
||||
def _any_state(self, name: str, equal: bool = True) -> ChromiumFilter: ...
|
||||
def _any_state(self, name: str, equal: bool = True) -> ChromiumFilter:
|
||||
"""
|
||||
:param name: 状态名称
|
||||
:param equal: 是否是指定状态,False表示否定状态
|
||||
:return: 选中的列表
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class Getter(object):
|
||||
_list: SessionElementsList = ...
|
||||
|
||||
def __init__(self, _list: SessionElementsList): ...
|
||||
def __init__(self, _list: SessionElementsList):
|
||||
"""
|
||||
:param _list: 元素列表对象
|
||||
"""
|
||||
...
|
||||
|
||||
def links(self) -> List[str]: ...
|
||||
def links(self) -> List[str]:
|
||||
"""返回所有元素的link属性组成的列表"""
|
||||
...
|
||||
|
||||
def texts(self) -> List[str]: ...
|
||||
def texts(self) -> List[str]:
|
||||
"""返回所有元素的text属性组成的列表"""
|
||||
...
|
||||
|
||||
def attrs(self, name: str) -> List[str]: ...
|
||||
def attrs(self, name: str) -> List[str]:
|
||||
"""返回所有元素指定的attr属性组成的列表
|
||||
:param name: 属性名称
|
||||
:return: 属性文本组成的列表
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def get_eles(locators: Union[List[str], tuple],
|
||||
owner: BaseParser,
|
||||
any_one: bool = False,
|
||||
first_ele: bool = True,
|
||||
timeout: float = 10) -> dict:
|
||||
"""传入多个定位符,获取多个ele
|
||||
:param locators: 定位符组成的列表
|
||||
:param owner: 页面或元素对象
|
||||
:param any_one: 是否找到任何一个即返回
|
||||
:param first_ele: 每个定位符是否只获取第一个元素
|
||||
:param timeout: 超时时间(秒)
|
||||
:return: 多个定位符组成的dict
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def get_frame(owner: BaseParser,
|
||||
loc_ind_ele: Union[str, int, tuple, ChromiumFrame, ChromiumElement],
|
||||
timeout: float = None) -> ChromiumFrame:
|
||||
"""获取页面中一个frame对象
|
||||
:param owner: 要在其中查找元素的对象
|
||||
:param loc_ind_ele: 定位符、iframe序号、ChromiumFrame对象,序号从1开始,可传入负数获取倒数第几个
|
||||
:param timeout: 查找元素超时时间(秒)
|
||||
:return: ChromiumFrame对象
|
||||
"""
|
||||
...
|
||||
|
@ -12,12 +12,8 @@ from .._functions.web import location_in_viewport
|
||||
|
||||
|
||||
class Actions:
|
||||
"""用于实现动作链的类"""
|
||||
|
||||
def __init__(self, owner):
|
||||
"""
|
||||
:param owner: ChromiumBase对象
|
||||
"""
|
||||
self.owner = owner
|
||||
self._dr = owner.driver
|
||||
self.modifier = 0 # 修饰符,Alt=1, Ctrl=2, Meta/Command=4, Shift=8
|
||||
@ -26,14 +22,6 @@ class Actions:
|
||||
self._holding = 'left'
|
||||
|
||||
def move_to(self, ele_or_loc, offset_x=None, offset_y=None, duration=.5):
|
||||
"""鼠标移动到元素中点,或页面上的某个绝对坐标。可设置偏移量
|
||||
当带偏移量时,偏移量相对于元素左上角坐标
|
||||
:param ele_or_loc: 元素对象、绝对坐标或文本定位符,坐标为tuple(int, int)形式
|
||||
:param offset_x: 偏移量x
|
||||
:param offset_y: 偏移量y
|
||||
:param duration: 拖动用时,传入0即瞬间到达
|
||||
:return: self
|
||||
"""
|
||||
is_loc = False
|
||||
mid_point = offset_x == offset_y is None
|
||||
if offset_x is None:
|
||||
@ -73,12 +61,6 @@ class Actions:
|
||||
return self
|
||||
|
||||
def move(self, offset_x=0, offset_y=0, duration=.5):
|
||||
"""鼠标相对当前位置移动若干位置
|
||||
:param offset_x: 偏移量x
|
||||
:param offset_y: 偏移量y
|
||||
:param duration: 拖动用时,传入0即瞬间到达
|
||||
:return: self
|
||||
"""
|
||||
duration = .02 if duration < .02 else duration
|
||||
num = int(duration * 50)
|
||||
|
||||
@ -99,93 +81,48 @@ class Actions:
|
||||
return self
|
||||
|
||||
def click(self, on_ele=None, times=1):
|
||||
"""点击鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'left', times).wait(.05)._release('left')
|
||||
return self
|
||||
|
||||
def r_click(self, on_ele=None, times=1):
|
||||
"""点击鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'right', times).wait(.05)._release('right')
|
||||
return self
|
||||
|
||||
def m_click(self, on_ele=None, times=1):
|
||||
"""点击鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'middle', times).wait(.05)._release('middle')
|
||||
return self
|
||||
|
||||
def hold(self, on_ele=None):
|
||||
"""按住鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'left')
|
||||
return self
|
||||
|
||||
def release(self, on_ele=None):
|
||||
"""释放鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
if on_ele:
|
||||
self.move_to(on_ele, duration=.2)
|
||||
self._release('left')
|
||||
return self
|
||||
|
||||
def r_hold(self, on_ele=None):
|
||||
"""按住鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'right')
|
||||
return self
|
||||
|
||||
def r_release(self, on_ele=None):
|
||||
"""释放鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
if on_ele:
|
||||
self.move_to(on_ele, duration=.2)
|
||||
self._release('right')
|
||||
return self
|
||||
|
||||
def m_hold(self, on_ele=None):
|
||||
"""按住鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
self._hold(on_ele, 'middle')
|
||||
return self
|
||||
|
||||
def m_release(self, on_ele=None):
|
||||
"""释放鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
if on_ele:
|
||||
self.move_to(on_ele, duration=.2)
|
||||
self._release('middle')
|
||||
return self
|
||||
|
||||
def _hold(self, on_ele=None, button='left', count=1):
|
||||
"""按下鼠标按键
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param button: 要按下的按键
|
||||
:param count: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
if on_ele:
|
||||
self.move_to(on_ele, duration=.2)
|
||||
self._dr.run('Input.dispatchMouseEvent', type='mousePressed', button=button, clickCount=count,
|
||||
@ -194,22 +131,12 @@ class Actions:
|
||||
return self
|
||||
|
||||
def _release(self, button):
|
||||
"""释放鼠标按键
|
||||
:param button: 要释放的按键
|
||||
:return: self
|
||||
"""
|
||||
self._dr.run('Input.dispatchMouseEvent', type='mouseReleased', button=button, clickCount=1,
|
||||
x=self.curr_x, y=self.curr_y, modifiers=self.modifier)
|
||||
self._holding = 'left'
|
||||
return self
|
||||
|
||||
def scroll(self, delta_y=0, delta_x=0, on_ele=None):
|
||||
"""滚动鼠标滚轮,可先移动到元素上
|
||||
:param delta_y: 滚轮变化值y
|
||||
:param delta_x: 滚轮变化值x
|
||||
:param on_ele: ChromiumElement元素
|
||||
:return: self
|
||||
"""
|
||||
if on_ele:
|
||||
self.move_to(on_ele, duration=.2)
|
||||
self._dr.run('Input.dispatchMouseEvent', type='mouseWheel', x=self.curr_x, y=self.curr_y,
|
||||
@ -217,38 +144,18 @@ class Actions:
|
||||
return self
|
||||
|
||||
def up(self, pixel):
|
||||
"""鼠标向上移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
return self.move(0, -pixel)
|
||||
|
||||
def down(self, pixel):
|
||||
"""鼠标向下移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
return self.move(0, pixel)
|
||||
|
||||
def left(self, pixel):
|
||||
"""鼠标向左移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
return self.move(-pixel, 0)
|
||||
|
||||
def right(self, pixel):
|
||||
"""鼠标向右移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
return self.move(pixel, 0)
|
||||
|
||||
def key_down(self, key):
|
||||
"""按下键盘上的按键,
|
||||
:param key: 使用Keys获取的按键,或'DEL'形式按键名称
|
||||
:return: self
|
||||
"""
|
||||
key = getattr(Keys, key.upper(), key)
|
||||
if key in ('\ue009', '\ue008', '\ue00a', '\ue03d'): # 如果上修饰符,添加到变量
|
||||
self.modifier |= modifierBit.get(key, 0)
|
||||
@ -261,10 +168,6 @@ class Actions:
|
||||
return self
|
||||
|
||||
def key_up(self, key):
|
||||
"""提起键盘上的按键
|
||||
:param key: 按键,特殊字符见Keys
|
||||
:return: self
|
||||
"""
|
||||
key = getattr(Keys, key.upper(), key)
|
||||
if key in ('\ue009', '\ue008', '\ue00a', '\ue03d'): # 如果上修饰符,添加到变量
|
||||
self.modifier ^= modifierBit.get(key, 0)
|
||||
@ -277,10 +180,6 @@ class Actions:
|
||||
return self
|
||||
|
||||
def type(self, keys):
|
||||
"""用模拟键盘按键方式输入文本,可输入字符串,也可输入组合键
|
||||
:param keys: 要按下的按键,特殊字符和多个文本可用list或tuple传入
|
||||
:return: self
|
||||
"""
|
||||
modifiers = []
|
||||
if not isinstance(keys, (str, tuple, list)):
|
||||
keys = str(keys)
|
||||
@ -304,25 +203,15 @@ class Actions:
|
||||
return self
|
||||
|
||||
def input(self, text):
|
||||
"""输入文本,也可输入组合键,组合键用tuple形式输入
|
||||
:param text: 文本值或按键组合
|
||||
:return: self
|
||||
"""
|
||||
input_text_or_keys(self.owner, text)
|
||||
return self
|
||||
|
||||
def wait(self, second, scope=None):
|
||||
"""等待若干秒,如传入两个参数,等待时间为这两个数间的一个随机数
|
||||
:param second: 秒数
|
||||
:param scope: 随机数范围
|
||||
:return: None
|
||||
"""
|
||||
self.owner.wait(second=second, scope=scope)
|
||||
return self
|
||||
|
||||
|
||||
def location_to_client(page, lx, ly):
|
||||
"""绝对坐标转换为视口坐标"""
|
||||
scroll_x = page._run_js('return document.documentElement.scrollLeft;')
|
||||
scroll_y = page._run_js('return document.documentElement.scrollTop;')
|
||||
return lx - scroll_x, ly - scroll_y
|
||||
|
@ -43,63 +43,207 @@ KEYS = Literal['NULL', 'CANCEL', 'HELP', 'BACKSPACE', 'meta',
|
||||
|
||||
|
||||
class Actions:
|
||||
"""用于实现动作链的类"""
|
||||
|
||||
owner: ChromiumBase = ...
|
||||
_dr: Driver = ...
|
||||
modifier: int = ...
|
||||
curr_x: float = ...
|
||||
curr_y: float = ...
|
||||
_holding: str = ...
|
||||
|
||||
def __init__(self, owner: ChromiumBase):
|
||||
self.owner: ChromiumBase = ...
|
||||
self._dr: Driver = ...
|
||||
self.modifier: int = ...
|
||||
self.curr_x: int = ...
|
||||
self.curr_y: int = ...
|
||||
self._holding: str = ...
|
||||
"""
|
||||
:param owner: ChromiumBase对象
|
||||
"""
|
||||
...
|
||||
|
||||
def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[float, float], str],
|
||||
offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions: ...
|
||||
offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions:
|
||||
"""鼠标移动到元素中点,或页面上的某个绝对坐标。可设置偏移量
|
||||
当带偏移量时,偏移量相对于元素左上角坐标
|
||||
:param ele_or_loc: 元素对象、绝对坐标或文本定位符,坐标为tuple(int, int)形式
|
||||
:param offset_x: 偏移量x
|
||||
:param offset_y: 偏移量y
|
||||
:param duration: 拖动用时,传入0即瞬间到达
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def move(self, offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions: ...
|
||||
def move(self, offset_x: float = 0, offset_y: float = 0, duration: float = .5) -> Actions:
|
||||
"""鼠标相对当前位置移动若干位置
|
||||
:param offset_x: 偏移量x
|
||||
:param offset_y: 偏移量y
|
||||
:param duration: 拖动用时,传入0即瞬间到达
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
|
||||
def click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions:
|
||||
"""点击鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def r_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
|
||||
def r_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions:
|
||||
"""点击鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def m_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions: ...
|
||||
def m_click(self, on_ele: Union[ChromiumElement, str] = None, times: int = 1) -> Actions:
|
||||
"""点击鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param times: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""按住鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""释放鼠标左键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def r_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def r_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""按住鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def r_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def r_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""释放鼠标右键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def m_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def m_hold(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""按住鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def m_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
def m_release(self, on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""释放鼠标中键,可先移动到元素上
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def _hold(self, on_ele: Union[ChromiumElement, str] = None, button: str = 'left',
|
||||
count: int = 1) -> Actions: ...
|
||||
def _hold(self,
|
||||
on_ele: Union[ChromiumElement, str] = None,
|
||||
button: str = 'left',
|
||||
count: int = 1) -> Actions:
|
||||
"""按下鼠标按键
|
||||
:param on_ele: ChromiumElement元素或文本定位符
|
||||
:param button: 要按下的按键
|
||||
:param count: 点击次数
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def _release(self, button: str) -> Actions: ...
|
||||
def _release(self, button: str) -> Actions:
|
||||
"""释放鼠标按键
|
||||
:param button: 要释放的按键
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def scroll(self, delta_y: int = 0, delta_x: int = 0,
|
||||
on_ele: Union[ChromiumElement, str] = None) -> Actions: ...
|
||||
on_ele: Union[ChromiumElement, str] = None) -> Actions:
|
||||
"""滚动鼠标滚轮,可先移动到元素上
|
||||
:param delta_y: 滚轮变化值y
|
||||
:param delta_x: 滚轮变化值x
|
||||
:param on_ele: ChromiumElement元素
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def up(self, pixel: int) -> Actions: ...
|
||||
def up(self, pixel: int) -> Actions:
|
||||
"""鼠标向上移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def down(self, pixel: int) -> Actions: ...
|
||||
def down(self, pixel: int) -> Actions:
|
||||
"""鼠标向下移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def left(self, pixel: int) -> Actions: ...
|
||||
def left(self, pixel: int) -> Actions:
|
||||
"""鼠标向左移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def right(self, pixel: int) -> Actions: ...
|
||||
def right(self, pixel: int) -> Actions:
|
||||
"""鼠标向右移动若干像素
|
||||
:param pixel: 鼠标移动的像素值
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def key_down(self, key: Union[KEYS, str]) -> Actions: ...
|
||||
def key_down(self, key: Union[KEYS, str]) -> Actions:
|
||||
"""按下键盘上的按键,
|
||||
:param key: 使用Keys获取的按键,或'DEL'形式按键名称
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def key_up(self, key: Union[KEYS, str]) -> Actions: ...
|
||||
def key_up(self, key: Union[KEYS, str]) -> Actions:
|
||||
"""提起键盘上的按键
|
||||
:param key: 按键,特殊字符见Keys
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def type(self, keys: Union[KEYS, str, list, tuple]) -> Actions: ...
|
||||
def type(self, keys: Union[KEYS, str, list, tuple]) -> Actions:
|
||||
"""用模拟键盘按键方式输入文本,可输入字符串,也可输入组合键
|
||||
:param keys: 要按下的按键,特殊字符和多个文本可用list或tuple传入
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def input(self, text: Any) -> Actions: ...
|
||||
def input(self, text: Any) -> Actions:
|
||||
"""输入文本,也可输入组合键,组合键用tuple形式输入
|
||||
:param text: 文本值或按键组合
|
||||
:return: self
|
||||
"""
|
||||
...
|
||||
|
||||
def wait(self, second: float, scope: float = None) -> Actions: ...
|
||||
def wait(self, second: float, scope: float = None) -> Actions:
|
||||
"""等待若干秒,如传入两个参数,等待时间为这两个数间的一个随机数
|
||||
:param second: 秒数
|
||||
:param scope: 随机数范围
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def location_to_client(page, lx: int, ly: int) -> tuple: ...
|
||||
def location_to_client(page: ChromiumBase, lx: int, ly: int) -> tuple:
|
||||
"""绝对坐标转换为视口坐标
|
||||
:param page: 页面对象
|
||||
:param lx: 绝对坐标x
|
||||
:param ly: 绝对坐标y
|
||||
:return: 视口坐标元组
|
||||
"""
|
||||
...
|
||||
|
@ -26,14 +26,9 @@ class Screencast(object):
|
||||
|
||||
@property
|
||||
def set_mode(self):
|
||||
"""返回用于设置录屏幕式的对象"""
|
||||
return ScreencastMode(self)
|
||||
|
||||
def start(self, save_path=None):
|
||||
"""开始录屏
|
||||
:param save_path: 录屏保存位置
|
||||
:return: None
|
||||
"""
|
||||
self.set_save_path(save_path)
|
||||
if self._path is None:
|
||||
raise ValueError('save_path必须设置。')
|
||||
@ -83,10 +78,6 @@ class Screencast(object):
|
||||
self._owner._run_js(js)
|
||||
|
||||
def stop(self, video_name=None):
|
||||
"""停止录屏
|
||||
:param video_name: 视频文件名,为None时以当前时间名命
|
||||
:return: 文件路径
|
||||
"""
|
||||
if video_name and not video_name.endswith('mp4'):
|
||||
video_name = f'{video_name}.mp4'
|
||||
name = f'{time()}.mp4' if not video_name else video_name
|
||||
@ -128,7 +119,7 @@ class Screencast(object):
|
||||
imgInfo = img.shape
|
||||
size = (imgInfo[1], imgInfo[0])
|
||||
|
||||
videoWrite = VideoWriter(path, VideoWriter_fourcc(*"mp4v"), 5, size)
|
||||
videoWrite = VideoWriter(path, VideoWriter_fourcc(*"H264"), 5, size)
|
||||
|
||||
for i in pic_list:
|
||||
img = imread(str(i))
|
||||
@ -139,10 +130,6 @@ class Screencast(object):
|
||||
return f'{self._path}{sep}{name}'
|
||||
|
||||
def set_save_path(self, save_path=None):
|
||||
"""设置保存路径
|
||||
:param save_path: 保存路径
|
||||
:return: None
|
||||
"""
|
||||
if save_path:
|
||||
save_path = Path(save_path)
|
||||
if save_path.exists() and save_path.is_file():
|
||||
@ -151,7 +138,6 @@ class Screencast(object):
|
||||
self._path = save_path
|
||||
|
||||
def _run(self):
|
||||
"""非节俭模式运行方法"""
|
||||
self._running = True
|
||||
path = self._tmp_path or self._path
|
||||
while self._enable:
|
||||
@ -160,7 +146,6 @@ class Screencast(object):
|
||||
self._running = False
|
||||
|
||||
def _onScreencastFrame(self, **kwargs):
|
||||
"""节俭模式运行方法"""
|
||||
path = self._tmp_path or self._path
|
||||
with open(f'{path}{sep}{kwargs["metadata"]["timestamp"]}.jpg', 'wb') as f:
|
||||
f.write(b64decode(kwargs['data']))
|
||||
@ -172,21 +157,16 @@ class ScreencastMode(object):
|
||||
self._screencast = screencast
|
||||
|
||||
def video_mode(self):
|
||||
"""持续视频模式,生成的视频没有声音"""
|
||||
self._screencast._mode = 'video'
|
||||
|
||||
def frugal_video_mode(self):
|
||||
"""设置节俭视频模式,页面有变化时才录制,生成的视频没有声音"""
|
||||
self._screencast._mode = 'frugal_video'
|
||||
|
||||
def js_video_mode(self):
|
||||
"""设置使用js录制视频模式,可生成有声音的视频,但需要手动启动"""
|
||||
self._screencast._mode = 'js_video'
|
||||
|
||||
def frugal_imgs_mode(self):
|
||||
"""设置节俭视频模式,页面有变化时才截图"""
|
||||
self._screencast._mode = 'frugal_imgs'
|
||||
|
||||
def imgs_mode(self):
|
||||
"""设置图片模式,持续对页面进行截图"""
|
||||
self._screencast._mode = 'imgs'
|
||||
|
@ -6,44 +6,84 @@
|
||||
@License : BSD 3-Clause.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
from typing import Union, Optional
|
||||
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
|
||||
|
||||
class Screencast(object):
|
||||
_owner: ChromiumBase = ...
|
||||
_path: Optional[Path] = ...
|
||||
_tmp_path: Optional[Path] = ...
|
||||
_running: bool = ...
|
||||
_enable: bool = ...
|
||||
_mode: str = ...
|
||||
|
||||
def __init__(self, owner: ChromiumBase):
|
||||
self._owner: ChromiumBase = ...
|
||||
self._path: Path = ...
|
||||
self._tmp_path: Path = ...
|
||||
self._running: bool = ...
|
||||
self._enable: bool = ...
|
||||
self._mode: str = ...
|
||||
"""
|
||||
:param owner: 页面对象
|
||||
"""
|
||||
|
||||
@property
|
||||
def set_mode(self) -> ScreencastMode: ...
|
||||
def set_mode(self) -> ScreencastMode:
|
||||
"""返回用于设置录屏幕式的对象"""
|
||||
...
|
||||
|
||||
def start(self, save_path: Union[str, Path] = None) -> None: ...
|
||||
def start(self, save_path: Union[str, Path] = None) -> None:
|
||||
"""开始录屏
|
||||
:param save_path: 录屏保存位置
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def stop(self, video_name: str = None) -> str: ...
|
||||
def stop(self, video_name: str = None) -> str:
|
||||
"""停止录屏
|
||||
:param video_name: 视频文件名,为None时以当前时间名命
|
||||
:return: 文件路径
|
||||
"""
|
||||
...
|
||||
|
||||
def set_save_path(self, save_path: Union[str, Path] = None) -> None: ...
|
||||
def set_save_path(self, save_path: Union[str, Path] = None) -> None:
|
||||
"""设置保存路径
|
||||
:param save_path: 保存路径
|
||||
:return: None
|
||||
"""
|
||||
...
|
||||
|
||||
def _run(self) -> None: ...
|
||||
def _run(self) -> None:
|
||||
"""非节俭模式运行方法"""
|
||||
...
|
||||
|
||||
def _onScreencastFrame(self, **kwargs) -> None: ...
|
||||
def _onScreencastFrame(self, **kwargs) -> None:
|
||||
"""节俭模式运行方法"""
|
||||
...
|
||||
|
||||
|
||||
class ScreencastMode(object):
|
||||
_screencast: Screencast = ...
|
||||
|
||||
def __init__(self, screencast: Screencast):
|
||||
self._screencast: Screencast = ...
|
||||
"""
|
||||
:param screencast: Screencast对象
|
||||
"""
|
||||
...
|
||||
|
||||
def video_mode(self) -> None: ...
|
||||
def video_mode(self) -> None:
|
||||
"""持续视频模式,生成的视频没有声音"""
|
||||
...
|
||||
|
||||
def frugal_video_mode(self) -> None: ...
|
||||
def frugal_video_mode(self) -> None:
|
||||
"""设置节俭视频模式,页面有变化时才录制,生成的视频没有声音"""
|
||||
...
|
||||
|
||||
def js_video_mode(self) -> None: ...
|
||||
def js_video_mode(self) -> None:
|
||||
"""设置使用js录制视频模式,可生成有声音的视频,但需要手动启动"""
|
||||
...
|
||||
|
||||
def frugal_imgs_mode(self) -> None: ...
|
||||
def frugal_imgs_mode(self) -> None:
|
||||
"""设置节俭视频模式,页面有变化时才截图"""
|
||||
...
|
||||
|
||||
def imgs_mode(self) -> None: ...
|
||||
def imgs_mode(self) -> None:
|
||||
"""设置图片模式,持续对页面进行截图"""
|
||||
...
|
||||
|
@ -23,9 +23,9 @@ class ElementStates(object):
|
||||
|
||||
@property
|
||||
def is_displayed(self):
|
||||
return not (self._ele.style('visibility') == 'hidden' or
|
||||
self._ele._run_js('return this.offsetParent === null;')
|
||||
or self._ele.style('display') == 'none' or self._ele.property('hidden'))
|
||||
return not (self._ele.style('visibility') == 'hidden'
|
||||
or self._ele.style('display') == 'none'
|
||||
or self._ele.property('hidden'))
|
||||
|
||||
@property
|
||||
def is_enabled(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user