在我的 python 脚本中,我当前使用 webdriver_manager (text) 来安装 chrome webdriver。该网络驱动程序用于创建 Selenium 驱动程序来导航网站并收集 HTML 数据。该脚本在 python 中运行时完美运行,但是当我使用 PyInstaller 并使用“--onefile”标志将其转换为 .app 时,代码无法按预期运行。我使用的是基于 Intel 的 Mac。
我认为这可能是 MacOS 和 chromedriver 的问题,因为在 Windows 上我已经能够将脚本编译为 .exe 并使 webdriver_manager 按预期工作。
我尝试了多种策略。这是我尝试的解决方案的简要描述,并附有错误代码。完整的功能位于底部。
在第一个 try 块中,在
chrome_driver_setup()
中,我尝试了遵循 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
在第二个 try 块中,我尝试使用 Selenium 中的服务命令。
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:
在第三个尝试块中,我尝试按照文档指南使用
chrome_autoinstaller
库text。
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
在第四个尝试块中我使用了开启器
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
在第五个尝试块中,我注意到 webdriver-manager 当作为 .app 运行时,不会将驱动程序创建为可执行文件,并且会将 THIRD_PARTY_NOTICES 附加到 chrome 驱动程序,使其无法运行。这是附加的错误
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
所有这些情况在 Mac 上将脚本转换为 .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
我在第五个尝试块中遇到了与你提到的类似的问题,我使用的是linux而不是MacOS,但这也许会有所帮助,两天前在驱动程序管理器github中提出了一个问题。
https://github.com/SergeyPirogov/webdriver_manager/issues/665
解决驱动程序路径问题的拉取请求已获得批准,因此可能只是更新到最新版本的库。
如果由于某种原因你不想更新到最新版本,你也可以手动调整驱动程序路径,在错误日志中你可以看到一个目录名称.wdm,所以在那里你应该找到一个drivers 目录和 drivers.json 文件。编辑 json 文件并将路径的一部分从 THIRD_PARTY_NOTICS.chromedriver 更改为 chromedriver。然后进入 .wdm/drivers/chromedriver/mac64/127.0.6533.57/chromedriver-mac-x64 并确保 chromedriver 文件具有执行权限。
我希望这有帮助。