Intel芯片Mac下PyInstaller打包.app时配置Webdriver Manager使用ChromeDriver
Mac下PyInstaller打包Selenium+webdriver-manager为.app后无法运行的问题
我编写了Python脚本,通过webdriver-manager安装ChromeDriver,再创建Selenium实例访问网站收集HTML数据。脚本在Python环境中运行完全正常,但使用PyInstaller的--onefile参数打包为.app应用后,程序无法正常工作。我使用的是Intel芯片的Mac电脑,Windows系统下打包成.exe可以正常运行,因此怀疑是MacOS与ChromeDriver的兼容问题。
已尝试的解决策略及对应报错
方案1:使用webdriver-manager默认安装方式
报错信息:INFO:webdriverSetup:ChromeDriver not working. trying ChromeDriverManager().install() Message: Unable to obtain driver for chrome; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location方案2:使用Selenium的Service命令
报错信息:INFO:__main:running INFO:webdriverSetup:Error. Attempting other default chrome webdriver setup: Message: Unable to obtain driver for chrome; For documentation on this error, please visit:方案3:使用chromedriver-autoinstaller库
报错信息:INFO:webdriverSetup:Error. Attempting autoinstaller: Message: Unable to obtain driver for chrome; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location方案4:使用自定义opener
报错信息:INFO:root:Downloading chromedriver (127.0.6533.57)... INFO:webdriverSetup:Error. Attempting opener thing: Message: Unable to obtain driver for chrome; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location方案5:手动修复驱动权限与文件指向问题
发现打包为.app后,webdriver-manager未将驱动设为可执行文件,还错误地将驱动路径指向了THIRD_PARTY_NOTICES.chromedriver文件,手动修正路径和权限后仍报错:NFO:WDM:====== WebDriver manager ====== INFO:WDM:Get LATEST chromedriver version for google-chrome INFO:WDM:Get LATEST chromedriver version for google-chrome INFO:WDM:Driver [/Users/bennet/.wdm/drivers/chromedriver/mac64/127.0.6533.57/chromedriver-mac-x64/THIRD_PARTY_NOTICES.chromedriver] found in cache INFO:webdriverSetup:ChromeDriverManager, /Users/bennet/.wdm/drivers/chromedriver/mac64/127.0.6533.57/chromedriver-mac-x64/chromedriver INFO:webdriverSetup:Tried everything and it's not working. Now attempting to remove driver and reinstall. Message: Unable to obtain driver for chrome; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location
所有方案在脚本模式下均能正常运行,但打包为.app后全部失效,恳请提供可行的解决方案。
完整函数代码
def get_driver(): if sys.platform in ["Linux", "darwin"]: try: return chrome_driver_setup() except Exception as e: logger.info(f"Tried everything and it's not working. Now attempting to remove driver and reinstall. \n {e}") driver_path = shutil.which('chromedriver') # Remove the folder and everything inside it if the path exists if driver_path: driver_folder = os.path.dirname(driver_path) shutil.rmtree(driver_folder) return chrome_driver_setup() elif sys.platform == "win32": return bing_driver_setup() def chrome_driver_setup(): chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") # Run Chrome in headless mode chrome_options.add_argument("--no-sandbox") # Bypass OS security model chrome_options.add_argument("--disable-dev-shm-usage") # Overcome limited resource problems def make_executable(path): # Change the file permissions to make it executable st = os.stat(path) os.chmod(path, st.st_mode | stat.S_IEXEC) def is_executable(file_path): # Check if the file is executable return os.path.isfile(file_path) and os.access(file_path, os.X_OK) def create_ssl_context(): context = ssl.create_default_context(cafile=certifi.where()) return context def create_opener(): # Create a custom opener with our SSL context context = create_ssl_context() opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context)) urllib.request.install_opener(opener) # I know this is disgusting. Please blame ChromeDriver and Pyinstaller with MacOS because they don't work well together try: print("Attempting default chrome webdriver setup") driver = webdriver.Chrome(options=chrome_options) return driver except Exception as e: try: logger.info(f"Error. Attempting other default chrome webdriver setup: \n {e}") service = ChromeService() driver = webdriver.Chrome(service=service, options=chrome_options) except Exception as e: try: logger.info(f"Error. Attempting autoinstaller: \n {e}") chromedriver_autoinstaller.install() driver = webdriver.Chrome() return driver except Exception as e: try: logger.info(f"Error. Attempting opener thing: \n {e}") create_opener() driver = webdriver.Chrome(options=chrome_options) return driver except Exception as e: logger.info(f"ChromeDriver not working. trying ChromeDriverManager().install() \n {e}") executable_path = ChromeDriverManager().install() # need to do this because it installs incorrectly sometimes if executable_path.endswith("THIRD_PARTY_NOTICES.chromedriver"): executable_path = executable_path.replace("THIRD_PARTY_NOTICES.chromedriver", "chromedriver") logger.info(f"ChromeDriverManager, {executable_path}") if not is_executable(executable_path): logger.warning(f"The file at {executable_path} is not executable. Attempting to fix permissions.") make_executable(executable_path) driver = webdriver.Chrome(options=chrome_options) return driver
内容的提问来源于stack exchange,提问作者Roman De Santos
相关产品推荐
相关产品推荐

