AWS Lambda中Selenium无法将Chrome默认下载路径改为/tmp如何解决
问题根因
你这套代码在本地能跑、Lambda里失效是踩了Lambda定制headless chromium的专属坑:
- 你放在
/opt下的第三方编译headless-chromium(serverless-chrome衍生版)不识别add_experimental_option传入的download.default_directory配置,只有通过DevTools协议下发的Page.setDownloadBehavior能生效,但你下发配置的时机不对——driver刚初始化就发配置,chromium导航到目标站点后会重置这部分参数,等于配置白写。 - 写的
mkdir -p /tmp完全多余,Lambda运行时默认就存在可写的/tmp目录,这是整个执行环境里唯一有持久化写权限的路径,不需要手动创建。 - 你加的
--headless是旧版无头模式,这个模式对下载行为的支持存在已知bug,部分场景下会把文件落到无权限的默认用户目录,或者直接存在内存里不落盘。 - 代码里同时用了
file_path变量和硬编码的/tmp当下载路径,两边配置不一致也会导致异常。
可直接落地的修复代码
把原有初始化逻辑替换成下面的内容,注意配置下发时机:
from selenium.webdriver.chrome.options import Options from selenium import webdriver import os import time opt = Options() opt.binary_location = '/opt/headless-chromium' # 切到新版无头模式,修复旧版无头的下载bug opt.add_argument('--headless=new') opt.add_argument('--no-sandbox') opt.add_argument('--disable-dev-shm-usage') opt.add_argument('--window-size=1920,1080') # 不要在experimental_option里传下载路径配置,Lambda层的chromium不认,反而会干扰DevTools配置 # 初始化driver,新版本Selenium用options参数,废弃了旧的chrome_options传参 driver = webdriver.Chrome( executable_path=os.environ.get('DRIVER'), options=opt ) # 注册DevTools协议命令,不要在初始化阶段就下发下载配置 driver.command_executor._commands["send_command"] = ( "POST", "/session/$sessionId/chromium/send_command", ) # --- 导航到目标业务页面的逻辑写在这里 --- # driver.get("你的目标网站地址") # 准备点击下载按钮之前,再下发下载路径配置,避免被页面导航重置 params = { "cmd": "Page.setDownloadBehavior", "params": { "behavior": "allow", "downloadPath": "/tmp", "eventsEnabled": True } } driver.execute("send_command", params) # --- 点击下载按钮的逻辑写在这里 --- # 下载是异步操作,等3秒后遍历/tmp确认文件 time.sleep(3) print("当前/tmp目录文件列表:", os.listdir('/tmp'))
排错注意事项
- 不要在
/tmp下建多级子目录当下载路径,如果一定要用子目录,必须在下发下载配置前手动创建并给755权限,chromium不会自动创建不存在的下载目录。 - 确认你用的Selenium版本≥4.0,低版本Selenium不识别
--headless=new参数,会自动回退到有bug的旧版无头模式。 - 不要硬编码下载文件名,部分站点会通过响应头动态返回文件名,直接遍历
/tmp找后缀匹配、修改时间最新的文件即可。 - Lambda给的/tmp目录默认空间是512MB,如果下载的文件超过这个大小,要在Lambda配置里把临时存储容量调大,否则会写盘失败。
内容的提问来源于stack exchange,提问作者Pranav Singh
相关产品推荐
相关产品推荐

