diff --git a/DrissionPage/config.py b/DrissionPage/config.py index f36212f..996e82c 100644 --- a/DrissionPage/config.py +++ b/DrissionPage/config.py @@ -140,10 +140,10 @@ class DriverOptions(Options): return self def remove_all_extensions(self): - """移除所有插件 \n - 因插件是以整个文件储存,难以移除其中一个,故如须设置则全部移除再重设 + """移除所有插件 \n :return: 当前对象 """ + # 因插件是以整个文件储存,难以移除其中一个,故如须设置则全部移除再重设 self._extensions = [] return self @@ -223,16 +223,22 @@ class DriverOptions(Options): if driver_path is not None: self._driver_path = format_path(driver_path) + if chrome_path is not None: self.binary_location = format_path(chrome_path) + if debugger_address is not None: self.debugger_address = debugger_address + if download_path is not None: self.experimental_options['prefs']['download.default_directory'] = format_path(download_path) + if user_data_path is not None: self.set_argument('--user-data-dir', format_path(user_data_path)) + if cache_path is not None: self.set_argument('--disk-cache-dir', format_path(cache_path)) + return self @@ -242,32 +248,39 @@ def _dict_to_chrome_options(options: dict) -> Options: :return: 保存浏览器配置的ChromeOptions对象 """ chrome_options = webdriver.ChromeOptions() + # 已打开的浏览器路径 if 'debugger_address' in options and options['debugger_address']: - # 控制已打开的浏览器 chrome_options.debugger_address = options['debugger_address'] + + # 创建新的浏览器 else: + # 浏览器的exe文件路径 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']: @@ -292,6 +305,7 @@ def _chrome_options_to_dict(options: Union[dict, DriverOptions, None]) -> Union[ re_dict['arguments'] = options.arguments re_dict['extensions'] = options.extensions re_dict['experimental_options'] = options.experimental_options + try: re_dict['driver_path'] = options.driver_path except: diff --git a/DrissionPage/drission.py b/DrissionPage/drission.py index 5cfee39..f9745fc 100644 --- a/DrissionPage/drission.py +++ b/DrissionPage/drission.py @@ -14,20 +14,20 @@ from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.webdriver import WebDriver from tldextract import extract -from .config import _dict_to_chrome_options, OptionsManager, _chrome_options_to_dict +from .config import OptionsManager, _dict_to_chrome_options, _chrome_options_to_dict class Drission(object): - """Drission类整合了WebDriver对象和HTLSession对象,可按要求创建、关闭及同步cookies""" + """Drission类用于管理WebDriver对象和Session对象,是驱动器的角色""" def __init__(self, driver_or_options: Union[WebDriver, dict, Options] = None, session_or_options: Union[Session, dict] = None, ini_path: str = None, proxy: dict = None): - """初始化,可接收现成的WebDriver和Session对象,或接收它们的配置信息 \n + """初始化,可接收现成的WebDriver和Session对象,或接收它们的配置信息生成对象 \n :param driver_or_options: driver对象或chrome设置,Options类或设置字典 - :param session_or_options: Session对象设置 + :param session_or_options: Session对象或设置 :param ini_path: ini文件路径 :param proxy: 代理设置 """ @@ -35,16 +35,28 @@ class Drission(object): self._driver = None self._driver_path = 'chromedriver' self._proxy = proxy + + # 若接收到Session对象,直接记录 if isinstance(session_or_options, Session): self._session = session_or_options + + # 否则记录其配置信息 else: + + # 若接收到配置信息则记录,否则从ini文件读取 if session_or_options is None: self._session_options = OptionsManager(ini_path).get_option('session_options') else: self._session_options = session_or_options + + # 若接收到WebDriver对象,直接记录 if isinstance(driver_or_options, WebDriver): self._driver = driver_or_options + + # 否则记录其配置信息 else: + + # 若接收到配置信息则记录,否则从ini文件读取 if driver_or_options is None: om = OptionsManager(ini_path) self._driver_options = om.get_option('chrome_options') @@ -57,14 +69,16 @@ class Drission(object): @property def session(self) -> Session: - """返回Session对象,如为None则按配置信息创建""" + """返回Session对象,如未初始化则按配置信息创建""" if self._session is None: self._session = Session() attrs = ['headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', 'cert', 'adapters', 'stream', 'trust_env', 'max_redirects'] + for i in attrs: if i in self._session_options: exec(f'self._session.{i} = self._session_options["{i}"]') + if self._proxy: self._session.proxies = self._proxy @@ -72,7 +86,7 @@ class Drission(object): @property def driver(self) -> WebDriver: - """返回WebDriver对象,如为None则按配置信息创建""" + """返回WebDriver对象,如未初始化则按配置信息创建""" if self._driver is None: if isinstance(self._driver_options, dict): options = _dict_to_chrome_options(self._driver_options) @@ -125,8 +139,10 @@ class Drission(object): :return: None """ self._proxy = proxies + if self._session: self._session.proxies = proxies + if self._driver: cookies = self._driver.get_cookies() url = self._driver.current_url @@ -140,7 +156,7 @@ class Drission(object): def cookies_to_session(self, copy_user_agent: bool = False, driver: WebDriver = None, session: Session = None) -> None: - """把driver对象的cookies复制到session对象 \n + """把driver对象的cookies复制到session对象 \n :param copy_user_agent: 是否复制ua信息 :param driver: 来源driver对象 :param session: 目标session对象 @@ -148,8 +164,10 @@ class Drission(object): """ driver = driver or self.driver session = session or self.session + if copy_user_agent: self.user_agent_to_session(driver, session) + for cookie in driver.get_cookies(): session.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain']) @@ -165,8 +183,10 @@ class Drission(object): driver = driver or self.driver session = session or self.session domain = urlparse(url).netloc + if not domain: raise Exception('Without specifying a domain') + # 翻译cookies for i in [x for x in session.cookies if domain in x.domain]: cookie_data = {'name': i.name, 'value': str(i.value), 'path': i.path, 'domain': i.domain} @@ -186,12 +206,15 @@ class Drission(object): cookie['domain'] = override_domain cookie_domain = cookie['domain'] if cookie['domain'][0] != '.' else cookie['domain'][1:] + try: browser_domain = extract(driver.current_url).fqdn except AttributeError: browser_domain = '' + if cookie_domain not in browser_domain: driver.get(f'http://{cookie_domain.lstrip("http://")}') + if 'expiry' in cookie: cookie['expiry'] = int(cookie['expiry']) @@ -221,7 +244,7 @@ class Drission(object): return False def user_agent_to_session(self, driver: WebDriver = None, session: Session = None) -> None: - """把driver的user-agent复制到session \n + """把driver的user-agent复制到session \n :param driver: 来源driver对象 :param session: 目标session对象 :return: None