本地Airflow部署导入Selenium时chromedriver意外退出问题排查
解决Airflow Docker环境下Selenium Chromedriver意外退出(状态码127)问题
错误原因分析
状态码127本质是依赖缺失或权限/环境不匹配:
- 仅安装Chromedriver但未安装Chrome浏览器,导致依赖库缺失
- 本地挂载的Chromedriver与容器系统(Linux)不兼容
- Airflow运行DAG时的用户(默认
airflow)无执行权限 - DAG解析阶段提前执行浏览器初始化,而非在任务运行阶段
分步解决方案
1. 构建包含完整Chrome环境的自定义Airflow镜像
不要仅安装Chromedriver,必须同步安装匹配版本的Chrome浏览器及所有依赖。示例Dockerfile:
FROM apache/airflow:2.4.3-python3.7 USER root # 安装基础依赖 RUN apt-get update && apt-get install -y \ wget gnupg unzip \ libglib2.0-0 libnss3 libgconf-2-4 libfontconfig1 \ libx11-xcb1 libxcb-dri3-0 libdrm2 libxshmfence1 libgbm1 libasound2 \ && rm -rf /var/lib/apt/lists/* # 添加Chrome源并安装稳定版 RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \ && apt-get update && apt-get install -y google-chrome-stable # 自动下载匹配版本的Chromedriver RUN CHROME_VERSION=$(google-chrome --version | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") \ && wget -O /tmp/chromedriver.zip https://storage.googleapis.com/chrome-for-testing-public/$CHROME_VERSION/linux64/chromedriver-linux64.zip \ && unzip /tmp/chromedriver.zip -d /usr/local/bin/ \ && mv /usr/local/bin/chromedriver-linux64/chromedriver /usr/local/bin/chromedriver \ && chmod +x /usr/local/bin/chromedriver \ && rm -rf /tmp/chromedriver.zip /usr/local/bin/chromedriver-linux64 USER airflow # 安装指定版本Selenium(与Chromedriver兼容) RUN pip install selenium==4.8.0
2. 修正Selenium初始化代码
适配Docker环境,使用容器内的Chromedriver路径,并添加更稳定的参数:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service def init_chrome_browser(url): options = Options() # Docker环境必备参数 options.add_argument('--no-sandbox') options.add_argument('--headless=new') # Selenium 4+推荐的无头模式,兼容性更好 options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-gpu') options.add_argument('--disable-extensions') options.add_argument('--window-size=1920,1080') options.add_argument('--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36') # 使用容器内预安装的Chromedriver路径 service = Service('/usr/local/bin/chromedriver') browser = webdriver.Chrome(service=service, options=options) browser.get(url) return browser
3. 确保浏览器初始化仅在任务运行阶段执行
禁止在DAG全局作用域调用init_chrome_browser,必须把初始化逻辑放在Operator的执行函数内:
from airflow import DAG from airflow.operators.python import PythonOperator from datetime import datetime def scrape_amazon_task(): # 仅在任务执行时初始化浏览器 browser = init_chrome_browser("https://www.amazon.it") # 执行爬取逻辑... browser.quit() with DAG( 'amazon_italy_scraper', start_date=datetime(2024, 1, 1), schedule_interval='@daily' ) as dag: scrape_task = PythonOperator( task_id='scrape_amazon_data', python_callable=scrape_amazon_task )
4. 验证容器环境
启动容器后,进入worker容器验证权限和依赖:
# 进入airflow-worker容器 docker exec -it airflow-worker bash # 切换到airflow用户 su airflow # 验证Chromedriver和Chrome版本匹配 chromedriver --version google-chrome --version # 手动运行初始化脚本,确认能启动浏览器 python -c "from your_script import init_chrome_browser; b=init_chrome_browser('https://www.google.com'); print('Browser started'); b.quit()"
内容的提问来源于stack exchange,提问作者emilenebd
相关产品推荐
相关产品推荐

