diff --git a/DrissionPage/chromium_driver.py b/DrissionPage/chromium_driver.py index 6b8d38b..45c9b45 100644 --- a/DrissionPage/chromium_driver.py +++ b/DrissionPage/chromium_driver.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from functools import partial from json import dumps, loads from queue import Queue, Empty diff --git a/DrissionPage/chromium_driver.pyi b/DrissionPage/chromium_driver.pyi index 79a416a..4b1179c 100644 --- a/DrissionPage/chromium_driver.pyi +++ b/DrissionPage/chromium_driver.pyi @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from queue import Queue from threading import Thread, Event from typing import Union, Callable diff --git a/DrissionPage/configs/chromium_options.py b/DrissionPage/configs/chromium_options.py index 58076c0..0c06d93 100644 --- a/DrissionPage/configs/chromium_options.py +++ b/DrissionPage/configs/chromium_options.py @@ -1,14 +1,18 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path -from shutil import rmtree +from tempfile import gettempdir, TemporaryDirectory -from DrissionPage.functions.tools import port_is_using +from DrissionPage.functions.tools import port_is_using, clean_folder from .options_manage import OptionsManager class ChromiumOptions(object): def __init__(self, read_file=True, ini_path=None): - """初始化,默认从文件读取设置 \n + """ :param read_file: 是否从默认ini文件中读取配置信息 :param ini_path: ini文件路径,为None则读取默认ini文件 """ @@ -17,7 +21,7 @@ class ChromiumOptions(object): self._prefs_to_del = [] if read_file: - self.ini_path = ini_path or str(Path(__file__).parent / 'configs.ini') + self.ini_path = str(ini_path) if ini_path else str(Path(__file__).parent / 'configs.ini') om = OptionsManager(self.ini_path) options = om.chrome_options @@ -45,6 +49,12 @@ class ChromiumOptions(object): self._timeouts = {'implicit': timeouts['implicit'], 'pageLoad': timeouts['page_load'], 'script': timeouts['script']} + + self._auto_port = options.get('auto_port', False) + if self._auto_port: + port, path = PortFinder().get_port() + self._debugger_address = f'127.0.0.1:{port}' + self.set_paths(user_data_path=path) return self.ini_path = None @@ -57,6 +67,7 @@ class ChromiumOptions(object): self._debugger_address = '127.0.0.1:9222' self._page_load_strategy = 'normal' self._proxy = None + self._auto_port = False @property def download_path(self): @@ -100,6 +111,7 @@ class ChromiumOptions(object): @debugger_address.setter def debugger_address(self, address): + """设置浏览器地址,格式ip:port""" self._debugger_address = address @property @@ -118,7 +130,7 @@ class ChromiumOptions(object): return self._prefs def set_argument(self, arg, value=None): - """设置浏览器配置的argument属性 \n + """设置浏览器配置的argument属性 :param arg: 属性名 :param value: 属性值,有值的属性传入值,没有的传入None,如传入False,删除该项 :return: 当前对象 @@ -130,7 +142,7 @@ class ChromiumOptions(object): return self def remove_argument(self, value): - """移除一个argument项 \n + """移除一个argument项 :param value: 设置项名,有值的设置项传入设置名称即可 :return: 当前对象 """ @@ -146,7 +158,7 @@ class ChromiumOptions(object): return self def add_extension(self, path): - """添加插件 \n + """添加插件 :param path: 插件路径,可指向文件夹 :return: 当前对象 """ @@ -157,7 +169,7 @@ class ChromiumOptions(object): return self def remove_extensions(self): - """移除所有插件 \n + """移除所有插件 :return: 当前对象 """ self._extensions = [] @@ -173,7 +185,7 @@ class ChromiumOptions(object): return self def remove_pref(self, arg): - """删除用户首选项设置,不能删除已设置到文件中的项 \n + """删除用户首选项设置,不能删除已设置到文件中的项 :param arg: 设置项名称 :return: 当前对象 """ @@ -181,7 +193,7 @@ class ChromiumOptions(object): return self def remove_pref_from_file(self, arg): - """删除用户配置文件中已设置的项 \n + """删除用户配置文件中已设置的项 :param arg: 设置项名称 :return: 当前对象 """ @@ -189,7 +201,7 @@ class ChromiumOptions(object): return self def set_timeouts(self, implicit=None, pageLoad=None, script=None): - """设置超时时间,单位为秒 \n + """设置超时时间,单位为秒 :param implicit: 默认超时时间 :param pageLoad: 页面加载超时时间 :param script: 脚本运行超时时间 @@ -205,7 +217,7 @@ class ChromiumOptions(object): return self def set_user(self, user='Default'): - """设置使用哪个用户配置文件夹 \n + """设置使用哪个用户配置文件夹 :param user: 用户文件夹名称 :return: 当前对象 """ @@ -214,7 +226,7 @@ class ChromiumOptions(object): return self def set_headless(self, on_off=True): - """设置是否隐藏浏览器界面 \n + """设置是否隐藏浏览器界面 :param on_off: 开或关 :return: 当前对象 """ @@ -222,7 +234,7 @@ class ChromiumOptions(object): return self.set_argument('--headless', on_off) def set_no_imgs(self, on_off=True): - """设置是否加载图片 \n + """设置是否加载图片 :param on_off: 开或关 :return: 当前对象 """ @@ -230,7 +242,7 @@ class ChromiumOptions(object): return self.set_argument('--blink-settings=imagesEnabled=false', on_off) def set_no_js(self, on_off=True): - """设置是否禁用js \n + """设置是否禁用js :param on_off: 开或关 :return: 当前对象 """ @@ -238,7 +250,7 @@ class ChromiumOptions(object): return self.set_argument('--disable-javascript', on_off) def set_mute(self, on_off=True): - """设置是否静音 \n + """设置是否静音 :param on_off: 开或关 :return: 当前对象 """ @@ -246,14 +258,14 @@ class ChromiumOptions(object): return self.set_argument('--mute-audio', on_off) def set_user_agent(self, user_agent): - """设置user agent \n + """设置user agent :param user_agent: user agent文本 :return: 当前对象 """ return self.set_argument('--user-agent', user_agent) def set_proxy(self, proxy): - """设置代理 \n + """设置代理 :param proxy: 代理url和端口 :return: 当前对象 """ @@ -261,7 +273,7 @@ class ChromiumOptions(object): return self.set_argument('--proxy-server', proxy) def set_page_load_strategy(self, value): - """设置page_load_strategy,可接收 'normal', 'eager', 'none' \n + """设置page_load_strategy,可接收 'normal', 'eager', 'none' selenium4以上版本才支持此功能 normal:默认情况下使用, 等待所有资源下载完成 eager:DOM访问已准备就绪, 但其他资源 (如图像) 可能仍在加载中 @@ -276,7 +288,7 @@ class ChromiumOptions(object): def set_paths(self, browser_path=None, local_port=None, debugger_address=None, download_path=None, user_data_path=None, cache_path=None): - """快捷的路径设置函数 \n + """快捷的路径设置函数 :param browser_path: 浏览器可执行文件路径 :param local_port: 本地端口号 :param debugger_address: 调试浏览器地址,例:127.0.0.1:9222 @@ -307,18 +319,22 @@ class ChromiumOptions(object): return self - def auto_port(self, data_path=None): - """自动获取可用端口 \n - :param data_path: 用户文件夹保存路径,为None则保存在当前路径 + def auto_port(self, on_off=True): + """自动获取可用端口 + :param on_off: 是否开启自动获取端口号 :return: 当前对象 """ - data_path = data_path or '' - port, path = PortFinder().get_port(data_path) - self.set_paths(local_port=port, user_data_path=path) + if on_off: + port, path = PortFinder().get_port() + self.set_paths(local_port=port, user_data_path=path) + self._auto_port = True + else: + self._auto_port = False + self._debugger_address = '127.0.0.1:9222' return self def save(self, path=None): - """保存设置到文件 \n + """保存设置到文件 :param path: ini文件的路径, None 保存到当前读取的配置文件,传入 'default' 保存到默认ini文件 :return: 保存文件的绝对路径 """ @@ -342,7 +358,8 @@ class ChromiumOptions(object): om = OptionsManager(self.ini_path or str(Path(__file__).parent / 'configs.ini')) # 设置chrome_options - attrs = ('debugger_address', 'binary_location', 'arguments', 'extensions', 'user', 'page_load_strategy') + attrs = ('debugger_address', 'binary_location', 'arguments', 'extensions', 'user', 'page_load_strategy', + 'auto_port') for i in attrs: om.set_item('chrome_options', i, self.__getattribute__(f'_{i}')) # 设置代理 @@ -372,26 +389,22 @@ class ChromiumOptions(object): class PortFinder(object): used_port = [] - @staticmethod - def get_port(path): - """查找一个可用端口 \n - :param path: 用户文件夹保存路径 + def __init__(self): + self.tmp_dir = Path(gettempdir()) / 'DrissionPageTempFolder' + self.tmp_dir.mkdir(parents=True, exist_ok=True) + if not PortFinder.used_port: + clean_folder(self.tmp_dir) + + def get_port(self): + """查找一个可用端口 :return: 可以使用的端口和用户文件夹路径组成的元组 """ - path = Path(path) for i in range(9600, 9800): if i in PortFinder.used_port or port_is_using('127.0.0.1', i): continue - path = path / f'userData{i}' - if not path.exists(): - PortFinder.used_port.append(i) - return i, str(path) - - try: - rmtree(path) - return i, str(path) - except PermissionError: - continue + path = TemporaryDirectory(dir=self.tmp_dir) + PortFinder.used_port.append(i) + return i, path.name raise OSError('未找到可用端口。') diff --git a/DrissionPage/configs/chromium_options.pyi b/DrissionPage/configs/chromium_options.pyi index 640bf2f..60dfd79 100644 --- a/DrissionPage/configs/chromium_options.pyi +++ b/DrissionPage/configs/chromium_options.pyi @@ -1,10 +1,14 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path from typing import Union, Tuple, Any class ChromiumOptions(object): - def __init__(self, read_file: bool = True, ini_path: str = None): + def __init__(self, read_file: bool = True, ini_path: Union[str, Path] = None): self.ini_path: str = ... self._driver_path: str = ... self._user_data_path: str = ... @@ -19,6 +23,7 @@ class ChromiumOptions(object): self._extensions: list = ... self._prefs: dict = ... self._prefs_to_del: list = ... + self._auto_port: bool = ... @property def download_path(self) -> str: ... @@ -93,7 +98,7 @@ class ChromiumOptions(object): debugger_address: str = None, download_path: Union[str, Path] = None, user_data_path: Union[str, Path] = None, cache_path: Union[str, Path] = None) -> ChromiumOptions: ... - def auto_port(self, data_path: Union[str, Path]=None) -> ChromiumOptions: ... + def auto_port(self, on_off: bool = True) -> ChromiumOptions: ... def save(self, path: Union[str, Path] = None) -> str: ... @@ -104,4 +109,4 @@ class PortFinder(object): used_port: list = ... @staticmethod - def get_port(path: Union[str, Path]) -> Tuple[int, str]: ... + def get_port() -> Tuple[int, str]: ... diff --git a/DrissionPage/configs/configs.ini b/DrissionPage/configs/configs.ini index 81e8e1f..dd02ce2 100644 --- a/DrissionPage/configs/configs.ini +++ b/DrissionPage/configs/configs.ini @@ -10,6 +10,7 @@ extensions = [] experimental_options = {'prefs': {'profile.default_content_settings.popups': 0, 'profile.default_content_setting_values': {'notifications': 2}, 'plugins.plugins_list': [{'enabled': False, 'name': 'Chrome PDF Viewer'}]}, 'useAutomationExtension': False, 'excludeSwitches': ['enable-automation']} page_load_strategy = normal user = Default +auto_port = True [session_options] headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'} diff --git a/DrissionPage/configs/driver_options.py b/DrissionPage/configs/driver_options.py index 2385857..dd45009 100644 --- a/DrissionPage/configs/driver_options.py +++ b/DrissionPage/configs/driver_options.py @@ -1,4 +1,8 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path from selenium.webdriver.chrome.options import Options @@ -12,7 +16,7 @@ class DriverOptions(Options): """ def __init__(self, read_file=True, ini_path=None): - """初始化,默认从文件读取设置 \n + """初始化,默认从文件读取设置 :param read_file: 是否从默认ini文件中读取配置信息 :param ini_path: ini文件路径,为None则读取默认ini文件 """ @@ -20,7 +24,7 @@ class DriverOptions(Options): self._user_data_path = None if read_file: - self.ini_path = ini_path or str(Path(__file__).parent / 'configs.ini') + self.ini_path = str(ini_path) if ini_path else str(Path(__file__).parent / 'configs.ini') om = OptionsManager(self.ini_path) options_dict = om.chrome_options @@ -74,7 +78,7 @@ class DriverOptions(Options): # -------------重写父类方法,实现链式操作------------- def add_argument(self, argument): - """添加一个配置项 \n + """添加一个配置项 :param argument: 配置项内容 :return: 当前对象 """ @@ -82,7 +86,7 @@ class DriverOptions(Options): return self def set_capability(self, name, value): - """设置一个capability \n + """设置一个capability :param name: capability名称 :param value: capability值 :return: 当前对象 @@ -91,7 +95,7 @@ class DriverOptions(Options): return self def add_extension(self, extension): - """添加插件 \n + """添加插件 :param extension: crx文件路径 :return: 当前对象 """ @@ -99,7 +103,7 @@ class DriverOptions(Options): return self def add_encoded_extension(self, extension): - """将带有扩展数据的 Base64 编码字符串添加到将用于将其提取到 ChromeDriver 的列表中 \n + """将带有扩展数据的 Base64 编码字符串添加到将用于将其提取到 ChromeDriver 的列表中 :param extension: 带有扩展数据的 Base64 编码字符串 :return: 当前对象 """ @@ -107,7 +111,7 @@ class DriverOptions(Options): return self def add_experimental_option(self, name, value): - """添加一个实验选项到浏览器 \n + """添加一个实验选项到浏览器 :param name: 选项名称 :param value: 选项值 :return: 当前对象 @@ -118,7 +122,7 @@ class DriverOptions(Options): # -------------重写父类方法结束------------- def save(self, path=None): - """保存设置到文件 \n + """保存设置到文件 :param path: ini文件的路径, None 保存到当前读取的配置文件,传入 'default' 保存到默认ini文件 :return: 保存文件的绝对路径 """ @@ -161,7 +165,7 @@ class DriverOptions(Options): return self.save('default') def remove_argument(self, value): - """移除一个argument项 \n + """移除一个argument项 :param value: 设置项名,有值的设置项传入设置名称即可 :return: 当前对象 """ @@ -177,7 +181,7 @@ class DriverOptions(Options): return self def remove_experimental_option(self, key): - """移除一个实验设置,传入key值删除 \n + """移除一个实验设置,传入key值删除 :param key: 实验设置的名称 :return: 当前对象 """ @@ -187,7 +191,7 @@ class DriverOptions(Options): return self def remove_all_extensions(self): - """移除所有插件 \n + """移除所有插件 :return: 当前对象 """ # 因插件是以整个文件储存,难以移除其中一个,故如须设置则全部移除再重设 @@ -195,7 +199,7 @@ class DriverOptions(Options): return self def set_argument(self, arg, value): - """设置浏览器配置的argument属性 \n + """设置浏览器配置的argument属性 :param arg: 属性名 :param value: 属性值,有值的属性传入值,没有的传入bool :return: 当前对象 @@ -209,7 +213,7 @@ class DriverOptions(Options): return self def set_timeouts(self, implicit=None, pageLoad=None, script=None): - """设置超时时间,设置单位为秒,selenium4以上版本有效 \n + """设置超时时间,设置单位为秒,selenium4以上版本有效 :param implicit: 查找元素超时时间 :param pageLoad: 页面加载超时时间 :param script: 脚本运行超时时间 @@ -225,7 +229,7 @@ class DriverOptions(Options): return self def set_headless(self, on_off=True): - """设置是否隐藏浏览器界面 \n + """设置是否隐藏浏览器界面 :param on_off: 开或关 :return: 当前对象 """ @@ -233,7 +237,7 @@ class DriverOptions(Options): return self.set_argument('--headless', on_off) def set_no_imgs(self, on_off=True): - """设置是否加载图片 \n + """设置是否加载图片 :param on_off: 开或关 :return: 当前对象 """ @@ -241,7 +245,7 @@ class DriverOptions(Options): return self.set_argument('--blink-settings=imagesEnabled=false', on_off) def set_no_js(self, on_off=True): - """设置是否禁用js \n + """设置是否禁用js :param on_off: 开或关 :return: 当前对象 """ @@ -249,7 +253,7 @@ class DriverOptions(Options): return self.set_argument('--disable-javascript', on_off) def set_mute(self, on_off=True): - """设置是否静音 \n + """设置是否静音 :param on_off: 开或关 :return: 当前对象 """ @@ -257,21 +261,21 @@ class DriverOptions(Options): return self.set_argument('--mute-audio', on_off) def set_user_agent(self, user_agent): - """设置user agent \n + """设置user agent :param user_agent: user agent文本 :return: 当前对象 """ return self.set_argument('--user-agent', user_agent) def set_proxy(self, proxy): - """设置代理 \n + """设置代理 :param proxy: 代理url和端口 :return: 当前对象 """ return self.set_argument('--proxy-server', proxy) def set_page_load_strategy(self, value): - """设置page_load_strategy,可接收 'normal', 'eager', 'none' \n + """设置page_load_strategy,可接收 'normal', 'eager', 'none' selenium4以上版本才支持此功能 normal:默认情况下使用, 等待所有资源下载完成 eager:DOM访问已准备就绪, 但其他资源 (如图像) 可能仍在加载中 @@ -286,7 +290,7 @@ class DriverOptions(Options): def set_paths(self, driver_path=None, chrome_path=None, browser_path=None, local_port=None, debugger_address=None, download_path=None, user_data_path=None, cache_path=None): - """快捷的路径设置函数 \n + """快捷的路径设置函数 :param driver_path: chromedriver.exe路径 :param chrome_path: chrome.exe路径 :param browser_path: 浏览器可执行文件路径 @@ -330,7 +334,7 @@ class DriverOptions(Options): def chrome_options_to_dict(options): - """把chrome配置对象转换为字典 \n + """把chrome配置对象转换为字典 :param options: chrome配置对象,字典或DriverOptions对象 :return: 配置字典 """ diff --git a/DrissionPage/configs/driver_options.pyi b/DrissionPage/configs/driver_options.pyi index 7590626..cb16b21 100644 --- a/DrissionPage/configs/driver_options.pyi +++ b/DrissionPage/configs/driver_options.pyi @@ -1,4 +1,8 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path from typing import Union, List @@ -7,7 +11,7 @@ from selenium.webdriver.chrome.options import Options class DriverOptions(Options): - def __init__(self, read_file: bool = True, ini_path: str = None): + def __init__(self, read_file: bool = True, ini_path: Union[str, Path] = None): self.ini_path: str = ... self._driver_path: str = ... self._user_data_path: str = ... diff --git a/DrissionPage/configs/options_manage.py b/DrissionPage/configs/options_manage.py index d184473..4107ba9 100644 --- a/DrissionPage/configs/options_manage.py +++ b/DrissionPage/configs/options_manage.py @@ -1,5 +1,8 @@ # -*- coding:utf-8 -*- - +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from configparser import RawConfigParser, NoSectionError, NoOptionError from pathlib import Path from pprint import pprint @@ -9,10 +12,10 @@ class OptionsManager(object): """管理配置文件内容的类""" def __init__(self, path=None): - """初始化,读取配置文件,如没有设置临时文件夹,则设置并新建 \n + """初始化,读取配置文件,如没有设置临时文件夹,则设置并新建 :param path: ini文件的路径,默认读取模块文件夹下的 """ - self.ini_path = str(Path(__file__).parent / 'configs.ini') if path == 'default' or path is None else path + self.ini_path = str(Path(__file__).parent / 'configs.ini') if path == 'default' or path is None else str(path) if not Path(self.ini_path).exists(): raise FileNotFoundError('ini文件不存在。') self._conf = RawConfigParser() @@ -26,7 +29,7 @@ class OptionsManager(object): return self.get_option(item) def get_value(self, section, item): - """获取配置的值 \n + """获取配置的值 :param section: 段名 :param item: 项名 :return: 项值 @@ -39,7 +42,7 @@ class OptionsManager(object): return None def get_option(self, section): - """把section内容以字典方式返回 \n + """把section内容以字典方式返回 :param section: 段名 :return: 段内容生成的字典 """ @@ -55,7 +58,7 @@ class OptionsManager(object): return option def set_item(self, section, item, value): - """设置配置值 \n + """设置配置值 :param section: 段名 :param item: 项名 :param value: 项值 @@ -66,7 +69,7 @@ class OptionsManager(object): return self def remove_item(self, section, item): - """删除配置值 \n + """删除配置值 :param section: 段名 :param item: 项名 :return: None @@ -75,7 +78,7 @@ class OptionsManager(object): return self def save(self, path=None): - """保存配置文件 \n + """保存配置文件 :param path: ini文件的路径,传入 'default' 保存到默认ini文件 :return: 保存路径 """ diff --git a/DrissionPage/configs/options_manage.pyi b/DrissionPage/configs/options_manage.pyi index 299c699..bd431f5 100644 --- a/DrissionPage/configs/options_manage.pyi +++ b/DrissionPage/configs/options_manage.pyi @@ -1,5 +1,8 @@ # -*- coding:utf-8 -*- - +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from configparser import RawConfigParser from typing import Any diff --git a/DrissionPage/configs/session_options.py b/DrissionPage/configs/session_options.py index c10a108..195fde9 100644 --- a/DrissionPage/configs/session_options.py +++ b/DrissionPage/configs/session_options.py @@ -1,5 +1,8 @@ # -*- coding:utf-8 -*- - +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path from DrissionPage.functions.web import cookies_to_tuple @@ -33,7 +36,7 @@ class SessionOptions(object): self._del_set = set() # 记录要从ini文件删除的参数 if read_file: - self.ini_path = ini_path or str(Path(__file__).parent / 'configs.ini') + self.ini_path = str(ini_path) if ini_path else str(Path(__file__).parent / 'configs.ini') om = OptionsManager(self.ini_path) options_dict = om.session_options diff --git a/DrissionPage/configs/session_options.pyi b/DrissionPage/configs/session_options.pyi index 37f4da9..10f3f9b 100644 --- a/DrissionPage/configs/session_options.pyi +++ b/DrissionPage/configs/session_options.pyi @@ -1,4 +1,8 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from pathlib import Path from typing import Any, Union, Tuple @@ -8,7 +12,7 @@ from requests.cookies import RequestsCookieJar class SessionOptions(object): - def __init__(self, read_file: bool = True, ini_path: str = None): + def __init__(self, read_file: bool = True, ini_path: Union[str, Path] = None): self.ini_path: str = ... self._download_path: str = ... self._headers: dict = ... @@ -108,4 +112,5 @@ class SessionOptions(object): def as_dict(self) -> dict: ... + def session_options_to_dict(options: Union[dict, SessionOptions, None]) -> Union[dict, None]: ... diff --git a/DrissionPage/easy_set.py b/DrissionPage/easy_set.py index bfbe211..fd856ea 100644 --- a/DrissionPage/easy_set.py +++ b/DrissionPage/easy_set.py @@ -52,7 +52,7 @@ def set_paths(driver_path=None, om = OptionsManager(ini_path) def format_path(path: str) -> str: - return path or '' + return str(path) if path else '' if driver_path is not None: om.set_item('paths', 'chromedriver_path', format_path(driver_path)) @@ -64,10 +64,10 @@ def set_paths(driver_path=None, om.set_item('chrome_options', 'binary_location', format_path(browser_path)) if local_port is not None: - om.set_item('chrome_options', 'debugger_address', format_path(f'127.0.0.1:{local_port}')) + om.set_item('chrome_options', 'debugger_address', f'127.0.0.1:{local_port}') if debugger_address is not None: - om.set_item('chrome_options', 'debugger_address', format_path(debugger_address)) + om.set_item('chrome_options', 'debugger_address', debugger_address) if download_path is not None: om.set_item('paths', 'download_path', format_path(download_path)) @@ -84,6 +84,19 @@ def set_paths(driver_path=None, check_driver_version(format_path(driver_path), format_path(browser_path)) +def use_auto_port(on_off=True, ini_path=None): + """设置启动浏览器时使用自动分配的端口和临时文件夹 + :param on_off: 是否开启自动端口 + :param ini_path: 要修改的ini文件路径 + :return: None + """ + if not isinstance(on_off, bool): + raise TypeError('on_off参数只能输入bool值。') + om = OptionsManager(ini_path) + om.set_item('chrome_options', 'auto_port', on_off) + om.save() + + def set_argument(arg, value=None, ini_path=None): """设置浏览器配置argument属性 :param arg: 属性名 @@ -91,9 +104,9 @@ def set_argument(arg, value=None, ini_path=None): :param ini_path: 要修改的ini文件路径 :return: None """ - do = ChromiumOptions(ini_path=ini_path) - do.set_argument(arg, value) - do.save() + co = ChromiumOptions(ini_path=ini_path) + co.set_argument(arg, value) + co.save() def set_headless(on_off=True, ini_path=None): diff --git a/DrissionPage/easy_set.pyi b/DrissionPage/easy_set.pyi index cf05f44..7c687ff 100644 --- a/DrissionPage/easy_set.pyi +++ b/DrissionPage/easy_set.pyi @@ -3,46 +3,50 @@ @Author : g1879 @Contact : g1879@qq.com """ +from pathlib import Path from typing import Union -def show_settings(ini_path: str = None) -> None: ... +def show_settings(ini_path: Union[str, Path] = None) -> None: ... -def set_paths(driver_path: str = None, - chrome_path: str = None, - browser_path: str = None, +def set_paths(driver_path: Union[str, Path] = None, + chrome_path: Union[str, Path] = None, + browser_path: Union[str, Path] = None, local_port: Union[int, str] = None, debugger_address: str = None, - download_path: str = None, - user_data_path: str = None, - cache_path: str = None, - ini_path: str = None, + download_path: Union[str, Path] = None, + user_data_path: Union[str, Path] = None, + cache_path: Union[str, Path] = None, + ini_path: Union[str, Path] = None, check_version: bool = False) -> None: ... -def set_argument(arg: str, value: Union[bool, str] = None, ini_path: str = None) -> None: ... +def use_auto_port(on_off: bool = True, ini_path: Union[str, Path] = None) -> None: ... -def set_headless(on_off: bool = True, ini_path: str = None) -> None: ... +def set_argument(arg: str, value: Union[bool, str] = None, ini_path: Union[str, Path] = None) -> None: ... -def set_no_imgs(on_off: bool = True, ini_path: str = None) -> None: ... +def set_headless(on_off: bool = True, ini_path: Union[str, Path] = None) -> None: ... -def set_no_js(on_off: bool = True, ini_path: str = None) -> None: ... +def set_no_imgs(on_off: bool = True, ini_path: Union[str, Path] = None) -> None: ... -def set_mute(on_off: bool = True, ini_path: str = None) -> None: ... +def set_no_js(on_off: bool = True, ini_path: Union[str, Path] = None) -> None: ... -def set_user_agent(user_agent: str, ini_path: str = None) -> None: ... +def set_mute(on_off: bool = True, ini_path: Union[str, Path] = None) -> None: ... -def set_proxy(proxy: str, ini_path: str = None) -> None: ... +def set_user_agent(user_agent: str, ini_path: Union[str, Path] = None) -> None: ... -def check_driver_version(driver_path: str = None, chrome_path: str = None) -> bool: ... +def set_proxy(proxy: str, ini_path: Union[str, Path] = None) -> None: ... + + +def check_driver_version(driver_path: Union[str, Path] = None, chrome_path: str = None) -> bool: ... # -------------------------自动识别chrome版本号并下载对应driver------------------------ diff --git a/DrissionPage/functions/browser.py b/DrissionPage/functions/browser.py index e84d3ac..f35571e 100644 --- a/DrissionPage/functions/browser.py +++ b/DrissionPage/functions/browser.py @@ -1,4 +1,8 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from json import load, dump from pathlib import Path from platform import system @@ -12,7 +16,7 @@ from .tools import port_is_using, get_exe_from_port def connect_browser(option): - """连接或启动浏览器 \n + """连接或启动浏览器 :param option: DriverOptions对象 :return: chrome 路径和进程对象组成的元组 """ @@ -116,7 +120,7 @@ def set_prefs(opt): def _run_browser(port, path: str, args) -> Popen: - """创建chrome进程 \n + """创建chrome进程 :param port: 端口号 :param path: 浏览器地址 :param args: 启动参数 diff --git a/DrissionPage/functions/browser.pyi b/DrissionPage/functions/browser.pyi index f233715..2324000 100644 --- a/DrissionPage/functions/browser.pyi +++ b/DrissionPage/functions/browser.pyi @@ -1,4 +1,8 @@ # -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" from typing import Union from DrissionPage.configs.chromium_options import ChromiumOptions diff --git a/DrissionPage/functions/locator.py b/DrissionPage/functions/locator.py index 1547e11..e60ae81 100644 --- a/DrissionPage/functions/locator.py +++ b/DrissionPage/functions/locator.py @@ -7,7 +7,7 @@ from re import split def get_loc(loc, translate_css=False): - """接收selenium定位元组或本库定位语法,转换为标准定位元组,可翻译css selector为xpath \n + """接收selenium定位元组或本库定位语法,转换为标准定位元组,可翻译css selector为xpath :param loc: selenium定位元组或本库定位语法 :param translate_css: 是否翻译css selector为xpath :return: DrissionPage定位元组 @@ -34,9 +34,9 @@ def get_loc(loc, translate_css=False): def str_to_loc(loc): - """处理元素查找语句 \n - 查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n - @表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n + """处理元素查找语句 + 查找方式:属性、tag name及属性、文本、xpath、css selector、id、class + @表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 """ loc_by = 'xpath' @@ -108,7 +108,7 @@ def str_to_loc(loc): def _make_single_xpath_str(tag: str, text: str) -> str: - """生成xpath语句 \n + """生成xpath语句 :param tag: 标签名 :param text: 待处理的字符串 :return: xpath字符串 @@ -145,7 +145,7 @@ def _make_single_xpath_str(tag: str, text: str) -> str: def _make_multi_xpath_str(tag: str, text: str) -> str: - """生成多属性查找的xpath语句 \n + """生成多属性查找的xpath语句 :param tag: 标签名 :param text: 待处理的字符串 :return: xpath字符串 @@ -185,7 +185,7 @@ def _make_multi_xpath_str(tag: str, text: str) -> str: def _make_search_str(search_str: str) -> str: - """将"转义,不知何故不能直接用 \ 来转义 \n + """将"转义,不知何故不能直接用 \ 来转义 :param search_str: 查询字符串 :return: 把"转义后的字符串 """ @@ -202,7 +202,7 @@ def _make_search_str(search_str: str) -> str: def translate_loc(loc): - """把By类型的loc元组转换为css selector或xpath类型的 \n + """把By类型的loc元组转换为css selector或xpath类型的 :param loc: By类型的loc元组 :return: css selector或xpath类型的loc元组 """ diff --git a/DrissionPage/functions/tools.py b/DrissionPage/functions/tools.py index a14aad2..4b1b9cc 100644 --- a/DrissionPage/functions/tools.py +++ b/DrissionPage/functions/tools.py @@ -10,7 +10,7 @@ from zipfile import ZipFile def get_exe_from_port(port): - """获取端口号第一条进程的可执行文件路径 \n + """获取端口号第一条进程的可执行文件路径 :param port: 端口号 :return: 可执行文件的绝对路径 """ @@ -25,7 +25,7 @@ def get_exe_from_port(port): def get_pid_from_port(port): - """获取端口号第一条进程的pid \n + """获取端口号第一条进程的pid :param port: 端口号 :return: 进程id """ @@ -50,7 +50,7 @@ def get_pid_from_port(port): def get_usable_path(path): - """检查文件或文件夹是否有重名,并返回可以使用的路径 \n + """检查文件或文件夹是否有重名,并返回可以使用的路径 :param path: 文件或文件夹路径 :return: 可用的路径,Path对象 """ @@ -78,7 +78,7 @@ def get_usable_path(path): def make_valid_name(full_name): - """获取有效的文件名 \n + """获取有效的文件名 :param full_name: 文件名 :return: 可用的文件名 """ @@ -104,7 +104,7 @@ def make_valid_name(full_name): def get_long(txt): - """返回字符串中字符个数(一个汉字是2个字符) \n + """返回字符串中字符个数(一个汉字是2个字符) :param txt: 字符串 :return: 字符个数 """ @@ -113,7 +113,7 @@ def get_long(txt): def port_is_using(ip, port): - """检查端口是否被占用 \n + """检查端口是否被占用 :param ip: 浏览器地址 :param port: 浏览器端口 :return: bool @@ -126,7 +126,7 @@ def port_is_using(ip, port): def clean_folder(folder_path, ignore=None): - """清空一个文件夹,除了ignore里的文件和文件夹 \n + """清空一个文件夹,除了ignore里的文件和文件夹 :param folder_path: 要清空的文件夹路径 :param ignore: 忽略列表 :return: None diff --git a/DrissionPage/functions/tools.pyi b/DrissionPage/functions/tools.pyi index 21584a0..a3673cb 100644 --- a/DrissionPage/functions/tools.pyi +++ b/DrissionPage/functions/tools.pyi @@ -25,7 +25,7 @@ def get_long(txt) -> int: ... def port_is_using(ip: str, port: Union[str, int]) -> bool: ... -def clean_folder(folder_path: str, ignore: list = None) -> None: ... +def clean_folder(folder_path: Union[str, Path], ignore: list = None) -> None: ... def unzip(zip_path: str, to_path: str) -> Union[list, None]: ...