def _create_chrome(chrome_path: str, port: str, args: list, proxy: dict) -> tuple: """创建 chrome 进程 \n :param chrome_path: chrome.exe 路径 :param port: 进程运行的端口号 :param args: chrome 配置参数 :return: chrome.exe 路径和进程对象组成的元组 """ from subprocess import Popen # ----------为路径加上双引号,避免路径中的空格产生异常---------- args1 = [] for arg in args: if arg.startswith(('--user-data-dir', '--disk-cache-dir')): index = arg.find('=') + 1 args1.append(f'{arg[:index]}"{arg[index:].strip()}"') else: args1.append(arg) args = ' '.join(set(args1)) if proxy: args = f'{args} --proxy-server={proxy["http"]}' # ----------创建浏览器进程---------- try: debugger = Popen( f'{chrome_path} --remote-debugging-port={port} {args}', shell=False) if chrome_path == 'chrome.exe': from common import get_exe_path_from_port chrome_path = get_exe_path_from_port(port) # 传入的路径找不到,主动在ini文件、注册表、系统变量中找 except FileNotFoundError: from DrissionPage.easy_set import _get_chrome_path chrome_path = _get_chrome_path(show_msg=False) if not chrome_path: raise FileNotFoundError('无法找到chrome.exe路径,请手动配置。') debugger = Popen( f'"{chrome_path}" --remote-debugging-port={port} {args}', shell=False) return chrome_path, debugger
def _create_driver(chrome_path: str, driver_path: str, options: Options) -> WebDriver: """创建 WebDriver 对象 \n :param chrome_path: chrome.exe 路径 :param driver_path: chromedriver.exe 路径 :param options: Options 对象 :return: WebDriver 对象 """ try: return webdriver.Chrome(driver_path, options=options) # 若版本不对,获取对应 chromedriver 再试 except (WebDriverException, SessionNotCreatedException): from .easy_set import get_match_driver chrome_path = None if chrome_path == 'chrome.exe' else chrome_path driver_path = get_match_driver(chrome_path=chrome_path, check_version=False, show_msg=False) if driver_path: try: return webdriver.Chrome(driver_path, options=options) except: pass # 当找不到 driver 且 chrome_path 为 None 时,说明安装的版本过高,改在系统路径中查找 elif chrome_path is None and driver_path is None: from DrissionPage.easy_set import _get_chrome_path chrome_path = _get_chrome_path(show_msg=False, from_ini=False, from_regedit=False) driver_path = get_match_driver(chrome_path=chrome_path, check_version=False, show_msg=False) if driver_path: options.binary_location = chrome_path try: return webdriver.Chrome(driver_path, options=options) except: pass print('无法启动,请检查chromedriver版本与Chrome是否匹配,并手动设置。') exit(0)
def _create_driver(chrome_path: str, driver_path: str, options: Options) -> WebDriver: """创建 WebDriver 对象 \n :param chrome_path: chrome.exe 路径 :param driver_path: chromedriver.exe 路径 :param options: Options 对象 :return: WebDriver 对象 """ try: debugger_address = options.debugger_address if options.debugger_address: options = Options() options.debugger_address = debugger_address return webdriver.Chrome(driver_path, options=options) # 若版本不对,获取对应 chromedriver 再试 except (WebDriverException, SessionNotCreatedException): print('打开失败,尝试获取driver。\n') from .easy_set import get_match_driver from DrissionPage.easy_set import _get_chrome_path if chrome_path == 'chrome.exe': chrome_path = _get_chrome_path(show_msg=False, from_ini=False) if chrome_path: driver_path = get_match_driver(chrome_path=chrome_path, check_version=False, show_msg=True) if driver_path: try: options.binary_location = chrome_path return webdriver.Chrome(driver_path, options=options) except Exception: pass print( '无法启动,请检查浏览器路径,或手动设置chromedriver。\n下载地址:http://npm.taobao.org/mirrors/chromedriver/' ) exit(0)
def driver(self) -> WebDriver: """返回WebDriver对象,如未初始化则按配置信息创建。 \n 如设置了本地调试浏览器,可自动接入或打开浏览器进程。 """ if self._driver is None: if isinstance(self._driver_options, dict): options = _dict_to_chrome_options(self._driver_options) else: raise TypeError('Driver options invalid') if self._proxy: options.add_argument(f'--proxy-server={self._proxy["http"]}') driver_path = self._driver_options.get('driver_path', None) or 'chromedriver' chrome_path = self._driver_options.get('binary_location', None) or 'chrome.exe' # -----------若指定debug端口且该端口未在使用中,则先启动浏览器进程----------- if options.debugger_address and _check_port( options.debugger_address) is False: from subprocess import Popen port = options.debugger_address[options.debugger_address. rfind(':') + 1:] try: self._debugger = Popen( f'{chrome_path} --remote-debugging-port={port}', shell=False) if chrome_path == 'chrome.exe': from common import get_exe_path_from_port chrome_path = get_exe_path_from_port(port) # 启动不了进程,主动找浏览器执行文件启动 except FileNotFoundError: from DrissionPage.easy_set import _get_chrome_path chrome_path = _get_chrome_path(show_msg=False) if not chrome_path: raise FileNotFoundError('无法找到chrome.exe路径,请手动配置。') self._debugger = Popen( f'"{chrome_path}" --remote-debugging-port={port}', shell=False) # -----------创建WebDriver对象----------- try: self._driver = webdriver.Chrome(driver_path, options=options) # 若版本不对,获取对应chromedriver再试 except (WebDriverException, SessionNotCreatedException): from .easy_set import get_match_driver chrome_path = None if chrome_path == 'chrome.exe' else chrome_path driver_path = get_match_driver(chrome_path=chrome_path, check_version=False, show_msg=False) if driver_path: try: self._driver = webdriver.Chrome(driver_path, options=options) except: print('无法启动,请检查chromedriver版本与Chrome是否匹配,并手动设置。') exit(0) # 当找不到driver且chrome_path为None时,说明安装的版本过高,改在系统路径中查找 elif chrome_path is None and driver_path is None: from DrissionPage.easy_set import _get_chrome_path chrome_path = _get_chrome_path(show_msg=False, from_ini=False, from_regedit=False) driver_path = get_match_driver(chrome_path=chrome_path, check_version=False, show_msg=False) if driver_path: options.binary_location = chrome_path try: self._driver = webdriver.Chrome(driver_path, options=options) except: print('无法启动,请检查chromedriver版本与Chrome是否匹配,并手动设置。') exit(0) else: print('无法启动,请检查chromedriver版本与Chrome是否匹配,并手动设置。') exit(0) else: print('无法启动,请检查chromedriver版本与Chrome是否匹配,并手动设置。') exit(0) # 反反爬设置 try: self._driver.execute_script( 'Object.defineProperty(navigator,"webdriver",{get:() => Chrome,});' ) except: pass # self._driver.execute_cdp_cmd( # 'Page.addScriptToEvaluateOnNewDocument', # {'source': 'Object.defineProperty(navigator,"webdriver",{get:() => Chrome,});'}) return self._driver