为何基于Selenium的Python脚本在AWS EC2上运行时冻结?
AWS EC2上Selenium Firefox无头进程冻结的解决方法
WebDriverWait用法错误:你当前的
WebDriverWait(driver, 3)只是初始化了等待对象,但没有指定等待条件,等于没做任何等待。EC2实例的网络或页面加载速度通常比本地慢,元素还没渲染出来就执行find_element会导致进程挂起。正确做法是用until方法等待元素可交互:# 替换无效的WebDriverWait代码 WebDriverWait(driver, 10).until(EC.element_to_be_clickable(("xpath", "//button[@class='sc-beySPh gNAvzR mde-consent-accept-btn']")))需提前导入依赖:
from selenium.webdriver.support import expected_conditions as ECEC2共享内存限制:AWS EC2默认的
/dev/shm分区很小,无头Firefox会因内存不足卡住,必须添加--disable-dev-shm-usage参数强制使用磁盘而非共享内存。如果是小规格实例(如t2.micro),建议再添加--memory-pressure-off禁用内存压力检测:options.add_argument("--disable-dev-shm-usage") options.add_argument("--memory-pressure-off")版本兼容性问题:EC2上安装的Firefox版本必须和你使用的geckodriver版本严格匹配(比如Firefox 115对应geckodriver 0.33.0),可通过以下命令检查版本:
firefox --version geckodriver --version不匹配则下载对应版本替换。
权限问题:确保geckodriver有执行权限,运行脚本的用户能访问该文件:
chmod +x /path/to/geckodriver
修改后的完整代码
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def get_source_content(url): driver_path = f"{settings.BASE_DIR}/geckodriver" options = FirefoxOptions() options.add_argument("--headless") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--single-process") options.add_argument("--ignore-certificate-errors") # 添加EC2专属优化参数 options.add_argument("--disable-dev-shm-usage") options.add_argument("--memory-pressure-off") driver = webdriver.Firefox(service=FirefoxService(executable_path=driver_path), options=options) try: driver.get(url) # 等待同意按钮可点击 WebDriverWait(driver, 10).until( EC.element_to_be_clickable(("xpath", "//button[@class='sc-beySPh gNAvzR mde-consent-accept-btn']")) ) element = driver.find_element("xpath", "//button[@class='sc-beySPh gNAvzR mde-consent-accept-btn']") element.click() # 等待页面加载完成 WebDriverWait(driver, 5).until( EC.presence_of_element_located(("tag name", "body")) ) source = driver.page_source except Exception as ex: # 出错时强制关闭driver,避免进程残留 driver.quit() raise ex driver.quit() return source
内容的提问来源于stack exchange,提问作者Alberto Sanmartin Martinez
相关产品推荐
相关产品推荐

