mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
timeouts的implicit改成base; debugger_address改成address ActionChains改成Actions; 一些文件和内部类改名; wait.data_packets()即将废弃; iframe切换了id也可继续监听; 修复监听器有时不能获取postData的问题; 修复监听器不能获取同域iframe数据包的问题; 修复等待数据包timeout无效问题
482 lines
14 KiB
Python
482 lines
14 KiB
Python
# -*- coding:utf-8 -*-
|
||
"""
|
||
@Author : g1879
|
||
@Contact : g1879@qq.com
|
||
"""
|
||
from pathlib import Path
|
||
|
||
from requests import Session
|
||
from requests.structures import CaseInsensitiveDict
|
||
|
||
from .options_manage import OptionsManager
|
||
from .._commons.web import cookies_to_tuple, set_session_cookies
|
||
|
||
|
||
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 = None
|
||
self._timeout = 10
|
||
self._del_set = set() # 记录要从ini文件删除的参数
|
||
|
||
self._headers = None
|
||
self._cookies = None
|
||
self._auth = None
|
||
self._proxies = None
|
||
self._hooks = None
|
||
self._params = None
|
||
self._verify = None
|
||
self._cert = None
|
||
self._adapters = None
|
||
self._stream = None
|
||
self._trust_env = None
|
||
self._max_redirects = None
|
||
self._retry_times = 3
|
||
self._retry_interval = 2
|
||
|
||
if read_file is False:
|
||
return
|
||
|
||
ini_path = str(ini_path) if ini_path else None
|
||
om = OptionsManager(ini_path)
|
||
self.ini_path = om.ini_path
|
||
|
||
options = om.session_options
|
||
if options.get('headers', None) is not None:
|
||
self.set_headers(options['headers'])
|
||
|
||
if options.get('cookies', None) is not None:
|
||
self.set_cookies(options['cookies'])
|
||
|
||
if options.get('auth', None) is not None:
|
||
self._auth = options['auth']
|
||
|
||
if options.get('params', None) is not None:
|
||
self._params = options['params']
|
||
|
||
if options.get('verify', None) is not None:
|
||
self._verify = options['verify']
|
||
|
||
if options.get('cert', None) is not None:
|
||
self._cert = options['cert']
|
||
|
||
if options.get('stream', None) is not None:
|
||
self._stream = options['stream']
|
||
|
||
if options.get('trust_env', None) is not None:
|
||
self._trust_env = options['trust_env']
|
||
|
||
if options.get('max_redirects', None) is not None:
|
||
self._max_redirects = options['max_redirects']
|
||
|
||
self.set_proxies(om.proxies.get('http', None), om.proxies.get('https', None))
|
||
self._timeout = om.timeouts.get('base', 10)
|
||
self._download_path = om.paths.get('download_path', None) or None
|
||
|
||
others = om.others
|
||
self._retry_times = others.get('retry_times', 3)
|
||
self._retry_interval = others.get('retry_interval', 2)
|
||
|
||
# ===========须独立处理的项开始============
|
||
@property
|
||
def download_path(self):
|
||
"""返回默认下载路径属性信息"""
|
||
return self._download_path
|
||
|
||
def set_download_path(self, path=None):
|
||
"""设置默认下载路径
|
||
:param path: 下载路径
|
||
:return: 返回当前对象
|
||
"""
|
||
self._download_path = 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:
|
||
self._retry_interval = interval
|
||
return self
|
||
|
||
# ===========须独立处理的项结束============
|
||
|
||
@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')
|
||
else:
|
||
self._headers = {key.lower(): headers[key] for key in headers}
|
||
return self
|
||
|
||
def set_a_header(self, attr, value):
|
||
"""设置headers中一个项
|
||
:param attr: 设置名称
|
||
:param value: 设置值
|
||
:return: 返回当前对象
|
||
"""
|
||
if self._headers is None:
|
||
self._headers = {}
|
||
|
||
self._headers[attr.lower()] = value
|
||
return self
|
||
|
||
def remove_a_header(self, attr):
|
||
"""从headers中删除一个设置
|
||
:param attr: 要删除的设置
|
||
:return: 返回当前对象
|
||
"""
|
||
if self._headers is None:
|
||
return self
|
||
|
||
attr = attr.lower()
|
||
self._headers.pop(attr, None)
|
||
|
||
return self
|
||
|
||
@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,可为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)
|
||
else:
|
||
self.__setattr__(f'_{arg}', val)
|
||
if arg in self._del_set:
|
||
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()
|
||
|
||
elif path is None:
|
||
if self.ini_path:
|
||
path = Path(self.ini_path).absolute()
|
||
else:
|
||
path = (Path(__file__).parent / 'configs.ini').absolute()
|
||
|
||
else:
|
||
path = Path(path).absolute()
|
||
|
||
path = path / 'config.ini' if path.is_dir() else path
|
||
|
||
if path.exists():
|
||
om = OptionsManager(str(path))
|
||
else:
|
||
om = OptionsManager(self.ini_path or str(Path(__file__).parent / 'configs.ini'))
|
||
|
||
options = session_options_to_dict(self)
|
||
|
||
for i in options:
|
||
if i not in ('download_path', 'timeout', 'proxies'):
|
||
om.set_item('session_options', i, options[i])
|
||
|
||
om.set_item('paths', 'download_path', self.download_path or '')
|
||
om.set_item('timeouts', 'base', self.timeout)
|
||
om.set_item('proxies', 'http', self.proxies.get('http', None))
|
||
om.set_item('proxies', 'https', self.proxies.get('https', None))
|
||
om.set_item('others', 'retry_times', self.retry_times)
|
||
om.set_item('others', 'retry_interval', self.retry_interval)
|
||
|
||
for i in self._del_set:
|
||
if i == 'download_path':
|
||
om.set_item('paths', 'download_path', '')
|
||
elif i == 'proxies':
|
||
om.set_item('proxies', 'http', '')
|
||
om.set_item('proxies', 'https', '')
|
||
else:
|
||
om.remove_item('session_options', i)
|
||
|
||
path = str(path)
|
||
om.save(path)
|
||
|
||
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对象,ua从对象中分离"""
|
||
s = Session()
|
||
h = CaseInsensitiveDict(self.headers) if self.headers else CaseInsensitiveDict()
|
||
|
||
if self.cookies:
|
||
set_session_cookies(s, self.cookies)
|
||
if self.adapters:
|
||
for url, adapter in self.adapters:
|
||
s.mount(url, adapter)
|
||
|
||
for i in ['auth', 'proxies', 'hooks', 'params', 'verify', 'cert', 'stream', 'trust_env', 'max_redirects']:
|
||
attr = self.__getattribute__(i)
|
||
if attr:
|
||
s.__setattr__(i, attr)
|
||
|
||
return s, h
|
||
|
||
def from_session(self, session, headers=None):
|
||
"""从Session对象中读取配置
|
||
:param session: Session对象
|
||
:param headers: headers
|
||
:return: 当前对象
|
||
"""
|
||
self._headers = CaseInsensitiveDict(**session.headers, **headers) if headers else session.headers
|
||
self._cookies = session.cookies
|
||
self._auth = session.auth
|
||
self._proxies = session.proxies
|
||
self._hooks = session.hooks
|
||
self._params = session.params
|
||
self._verify = session.verify
|
||
self._cert = session.cert
|
||
self._stream = session.stream
|
||
self._trust_env = session.trust_env
|
||
self._max_redirects = session.max_redirects
|
||
if session.adapters:
|
||
self._adapters = [(k, i) for k, i in session.adapters.items()]
|
||
return self
|
||
|
||
# --------------即将废弃---------------
|
||
|
||
def set_paths(self, download_path=None):
|
||
"""设置默认下载路径
|
||
:param download_path: 下载路径
|
||
:return: 返回当前对象
|
||
"""
|
||
if download_path is not None:
|
||
self._download_path = str(download_path)
|
||
return self
|
||
|
||
|
||
def session_options_to_dict(options):
|
||
"""把session配置对象转换为字典
|
||
:param options: session配置对象或字典
|
||
:return: 配置字典
|
||
"""
|
||
if options in (False, None):
|
||
return SessionOptions(read_file=False).as_dict()
|
||
|
||
if isinstance(options, dict):
|
||
return options
|
||
|
||
re_dict = dict()
|
||
attrs = ['headers', 'cookies', 'proxies', 'params', 'verify', 'stream', 'trust_env', 'cert',
|
||
'max_redirects', 'timeout', 'download_path']
|
||
|
||
for attr in attrs:
|
||
val = options.__getattribute__(f'_{attr}')
|
||
if val is not None:
|
||
re_dict[attr] = val
|
||
|
||
return re_dict
|