第二代Google Cloud Function Python Selenium报Chrome启动异常错误
问题描述
遇到与Chrome启动异常经典报错完全一致的问题,但对齐Chrome与ChromeDriver版本的常规修复方案无效。
当前在基于Cloud Run的第二代Google Cloud Functions环境中运行Selenium,使用基础测试代码如下:
测试代码
main.py
def hello_world(request): print("Start") from selenium import webdriver from selenium.webdriver.chrome.options import Options from chromedriver_py import binary_path from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager chrome_options = Options() chrome_options.binary_location=binary_path chrome_options.add_argument("--remote-debugging-port=9222") chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--window-size=1920x1080") chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-extensions') driver = webdriver.Chrome(options=chrome_options,service=Service(ChromeDriverManager().install())) driver.get("https://www.google.com") print(driver.title) driver.close() print("End") return "Empty - nothing"
requirements.txt
selenium >= 4.2.0 webdriver-manager >= 3.7.0 chromedriver_py >= 103.0.5060.24
代码运行时抛出错误:selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally。
有资料指出初代Cloud Functions无法兼容Selenium,但当前使用的是基于Cloud Run的第二代环境,需要可行方案让Selenium正常运行。
解决方案
第二代Cloud Functions(底层为Cloud Run)完全支持运行Selenium,报错来自三个核心配置错误,按以下步骤修改即可修复:
- 修正二进制路径配置错误
你当前把binary_location(Chrome浏览器本身的启动路径)设置成了chromedriver_py提供的ChromeDriver路径,这是最核心的配置错误:chromedriver_py包仅提供ChromeDriver驱动程序,不包含Chrome浏览器本体,而Cloud Functions默认运行镜像中也没有预装Chrome,自然会出现启动失败。
不需要手动指定binary_location,也不需要同时使用chromedriver_py和webdriver-manager,直接使用高版本webdriver-manager自动安装适配的Chromium浏览器和对应版本驱动即可,Selenium 4.6+也内置了Selenium Manager可以自动完成版本匹配,不需要额外配置路径。 - 补全容器环境必需的Chrome启动参数
你当前缺少无服务器容器环境下运行Headless Chrome的必需参数,同时配置了会引发冲突的参数:- 追加
--disable-dev-shm-usage参数,解决容器内/dev/shm共享内存空间不足导致Chrome崩溃的问题 - 用
--headless=new替换旧的--headless参数,新版Chrome(112+版本)的新Headless模式兼容性更好 - 追加
--disable-software-rasterizer参数,禁用软件光栅化减少运行异常 - 删除
--remote-debugging-port=9222参数,Cloud Functions环境不允许手动绑定固定调试端口,该配置会引发端口权限或占用问题
你已经添加的--no-sandbox、--disable-gpu、--window-size、--disable-extensions参数保留即可。
- 追加
- 调整函数运行资源配置
Headless Chrome启动和运行对内存有最低要求,默认的256MB内存配置会直接导致Chrome进程因内存不足被系统杀死,最低需要分配512MB内存,推荐分配1GB及以上内存,同时将函数超时时间设置为60秒以上,给Chrome启动、页面加载预留足够时间。
可直接运行的修正后代码
requirements.txt
selenium>=4.10.0 webdriver-manager>=4.0.0
main.py
def hello_world(request): print("Start") from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from webdriver_manager.core.os_manager import ChromeType chrome_options = Options() # 容器环境必需启动参数 chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--window-size=1920x1080") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--disable-extensions") chrome_options.add_argument("--disable-software-rasterizer") # 自动安装匹配版本的Chromium和对应驱动 service = Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()) driver = webdriver.Chrome(service=service, options=chrome_options) driver.get("https://www.google.com") print(driver.title) driver.quit() # 用quit()代替close(),彻底清理Chrome进程避免残留 print("End") return "Empty - nothing"
注意:部署时如果需要访问公网站点,确认函数的出口网络配置正确,避免因网络不通导致页面加载超时。
内容的提问来源于stack exchange,提问作者Ryszard Kozłowski
相关产品推荐
相关产品推荐

