mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
158 lines
6.9 KiB
Python
158 lines
6.9 KiB
Python
# -*- coding:utf-8 -*-
|
||
"""
|
||
配置文件
|
||
@Author : g1879
|
||
@Contact : g1879@qq.com
|
||
@File : config.py
|
||
"""
|
||
from configparser import ConfigParser, NoSectionError, NoOptionError
|
||
from pathlib import Path
|
||
from typing import Any, Union
|
||
|
||
from selenium import webdriver
|
||
from selenium.webdriver.chrome.options import Options
|
||
|
||
|
||
class OptionsManager(object):
|
||
"""管理配置文件内容的类"""
|
||
|
||
def __init__(self, path: str = None):
|
||
"""初始化,读取配置文件,如没有设置临时文件夹,则设置并新建
|
||
:param path: ini文件的路径,默认读取模块文件夹下的
|
||
"""
|
||
self.path = path or Path(__file__).parent / 'configs.ini'
|
||
self._conf = ConfigParser()
|
||
self._conf.read(self.path, encoding='utf-8')
|
||
if 'global_tmp_path' not in self.get_option('paths') or not self.get_value('paths', 'global_tmp_path'):
|
||
global_tmp_path = str((Path(__file__).parent / 'tmp').absolute())
|
||
Path(global_tmp_path).mkdir(parents=True, exist_ok=True)
|
||
self.set_item('paths', 'global_tmp_path', global_tmp_path)
|
||
self.save()
|
||
|
||
def get_value(self, section: str, item: str) -> Any:
|
||
"""获取配置的值"""
|
||
try:
|
||
return eval(self._conf.get(section, item))
|
||
except SyntaxError:
|
||
return self._conf.get(section, item)
|
||
except NoSectionError and NoOptionError:
|
||
return None
|
||
|
||
def get_option(self, section: str) -> dict:
|
||
"""把section内容以字典方式返回"""
|
||
items = self._conf.items(section)
|
||
option = dict()
|
||
for j in items:
|
||
try:
|
||
option[j[0]] = eval(self._conf.get(section, j[0]).replace('\\', '\\\\'))
|
||
except SyntaxError:
|
||
option[j[0]] = self._conf.get(section, j[0])
|
||
return option
|
||
|
||
def set_item(self, section: str, item: str, value: str) -> None:
|
||
"""设置配置值"""
|
||
self._conf.set(section, item, str(value))
|
||
|
||
def save(self, path: str = None) -> None:
|
||
"""保存配置文件
|
||
:param path: ini文件的路径,默认保存到模块文件夹下的
|
||
:return: None
|
||
"""
|
||
path = path or Path(__file__).parent / 'configs.ini'
|
||
self._conf.write(open(path, 'w', encoding='utf-8'))
|
||
|
||
|
||
class DriverOptions(Options):
|
||
def __init__(self, read_file=True):
|
||
"""初始化,默认从文件读取设置"""
|
||
super().__init__()
|
||
if read_file:
|
||
options_dict = OptionsManager().get_option('chrome_options')
|
||
self._binary_location = options_dict['binary_location'] if 'binary_location' in options_dict else ''
|
||
self._arguments = options_dict['arguments'] if 'arguments' in options_dict else []
|
||
self._extensions = options_dict['extensions'] if 'extensions' in options_dict else []
|
||
self._experimental_options = options_dict[
|
||
'experimental_options'] if 'experimental_options' in options_dict else {}
|
||
self._debugger_address = options_dict['debugger_address'] if 'debugger_address' in options_dict else None
|
||
|
||
def save(self, path: str = None) -> None:
|
||
"""保存设置到文件
|
||
:param path: ini文件的路径,默认保存到模块文件夹下的
|
||
:return: None
|
||
"""
|
||
om = OptionsManager()
|
||
options = _chrome_options_to_dict(self)
|
||
for i in options:
|
||
om.set_item('chrome_options', i, options[i])
|
||
om.save(path)
|
||
|
||
def remove_argument(self, value: str) -> None:
|
||
"""移除一个设置"""
|
||
if value in self._arguments:
|
||
self._arguments.remove(value)
|
||
|
||
def remove_experimental_option(self, key: str) -> None:
|
||
"""移除一个实验设置,传入key值删除"""
|
||
if key in self._experimental_options:
|
||
self._experimental_options.pop(key)
|
||
|
||
def remove_all_extensions(self) -> None:
|
||
"""移除所有插件
|
||
因插件是以整个文件储存,难以移除其中一个,故如须设置则全部移除再重设"""
|
||
self._extensions = []
|
||
|
||
|
||
def _dict_to_chrome_options(options: dict) -> Options:
|
||
"""从传入的字典获取浏览器设置,返回ChromeOptions对象"""
|
||
chrome_options = webdriver.ChromeOptions()
|
||
if 'debugger_address' in options and options['debugger_address']:
|
||
# 控制已打开的浏览器
|
||
chrome_options.debugger_address = options['debugger_address']
|
||
else:
|
||
if 'binary_location' in options and options['binary_location']:
|
||
# 手动指定使用的浏览器位置
|
||
chrome_options.binary_location = options['binary_location']
|
||
if 'arguments' in options:
|
||
# 启动参数
|
||
if not isinstance(options['arguments'], list):
|
||
raise Exception(f'Arguments need list,not {type(options["arguments"])}.')
|
||
for arg in options['arguments']:
|
||
chrome_options.add_argument(arg)
|
||
if 'extension_files' in options and options['extension_files']:
|
||
# 加载插件
|
||
if not isinstance(options['extension_files'], list):
|
||
raise Exception(f'Extension files need list,not {type(options["extension_files"])}.')
|
||
for arg in options['extension_files']:
|
||
chrome_options.add_extension(arg)
|
||
if 'extensions' in options and options['extensions']:
|
||
if not isinstance(options['extensions'], list):
|
||
raise Exception(f'Extensions need list,not {type(options["extensions"])}.')
|
||
for arg in options['extensions']:
|
||
chrome_options.add_encoded_extension(arg)
|
||
if 'experimental_options' in options and options['experimental_options']:
|
||
# 实验性质的设置参数
|
||
if not isinstance(options['experimental_options'], dict):
|
||
raise Exception(f'Experimental options need dict,not {type(options["experimental_options"])}.')
|
||
for i in options['experimental_options']:
|
||
chrome_options.add_experimental_option(i, options['experimental_options'][i])
|
||
# if 'capabilities' in options and options['capabilities']:
|
||
# pass # 未知怎么用
|
||
return chrome_options
|
||
|
||
|
||
def _chrome_options_to_dict(options: Union[dict, Options, None]) -> Union[dict, None]:
|
||
if options is None or isinstance(options, dict):
|
||
return options
|
||
|
||
re_dict = dict()
|
||
if options.debugger_address:
|
||
re_dict['debugger_address'] = options.debugger_address
|
||
else:
|
||
re_dict['binary_location'] = options.binary_location
|
||
re_dict['debugger_address'] = options.debugger_address
|
||
re_dict['arguments'] = options.arguments
|
||
re_dict['extensions'] = options.extensions
|
||
re_dict['experimental_options'] = options.experimental_options
|
||
# re_dict['capabilities'] = options.capabilities
|
||
return re_dict
|