在AWS Lambda运行Python Selenium时遇只读文件系统错误,求解决方案
问题分析与解决方案
问题概述
在AWS Lambda运行Python Selenium(基于undetected-chromedriver)脚本时,触发只读文件系统错误,错误指向/home/sbx_user1051目录,即使已设置data_dir='/tmp'仍未解决。环境版本:
- Python: v3.9
- Selenium: v4.6.1
- undetected-chrome-driver: v3.1.7
错误日志:
{ "errorMessage": "[Errno 30] Read-only file system: '/home/sbx_user1051'", "errorType": "OSError", "requestId": "820cf57b-8fd7-4ee4-82b9-6f93178ec148", "stackTrace": [ " File \"/var/task/handler.py\", line 34, in crawler\n browser = uc.Chrome(options=options, data_dir='/tmp')\n", " File \"/opt/python/lib/python3.9/site-packages/undetected_chromedriver/__init__.py\", line 237, in __init__\n patcher = Patcher(\n", " File \"/opt/python/lib/python3.9/site-packages/undetected_chromedriver/patcher.py\", line 66, in __init__\n os.makedirs(self.data_path, exist_ok=True)\n", " File \"/var/lang/lib/python3.9/os.py\", line 215, in makedirs\n makedirs(head, exist_ok=exist_ok)\n", " File \"/var/lang/lib/python3.9/os.py\", line 215, in makedirs\n makedirs(head, exist_ok=exist_ok)\n", " File \"/var/lang/lib/python3.9/os.py\", line 215, in makedirs\n makedirs(head, exist_ok=exist_ok)\n", " File \"/var/lang/lib/python3.9/os.py\", line 225, in makedirs\n mkdir(name, mode)\n" ] }
核心原因
undetected-chromedriver的Patcher模块默认会在用户主目录创建补丁文件,仅设置data_dir无法覆盖这一行为;同时Lambda环境中仅/tmp目录具备可写权限,其他目录均为只读。
解决方案
1. 强制指定所有可写路径到/tmp
修改ChromeOptions和undetected-chromedriver初始化参数,将所有需要写入的目录都指向/tmp下的子目录:
def crawler(event, context): options = webdriver.ChromeOptions() options.headless = True # Lambda无图形界面,必须启用无头模式 # 指定Chrome用户数据和缓存目录到/tmp options.add_argument("--user-data-dir=/tmp/chrome_user_data") options.add_argument("--disk-cache-dir=/tmp/chrome_cache") # 禁用不必要的功能,减少磁盘写入 options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") # 初始化浏览器时,显式指定补丁工作目录和数据目录 browser = uc.Chrome( options=options, data_dir='/tmp/undetected_chromedriver_data', patcher_kwargs={'data_path': '/tmp/undetected_chromedriver_patch'} ) try: # ... 你的业务逻辑代码 return responseGenerator("End of crawler execution", None, 205) finally: # 确保关闭浏览器释放资源 browser.quit()
2. 部署Chrome二进制文件到Lambda层
Lambda默认无Chrome环境,需将适配Amazon Linux 2的Chrome二进制文件打包成Lambda层:
- 下载对应版本的Chrome(推荐使用
chromium-browser的Amazon Linux 2兼容包) - 将Chrome二进制文件放入
opt/chrome目录,打包成zip - 在Lambda函数中添加该层,并指定Chrome路径:
options.binary_location = "/opt/chrome/chrome"
3. 调整undetected-chromedriver版本
部分旧版本的undetected-chromedriver在Lambda环境下存在路径处理bug,尝试升级到最新稳定版,或降级至v3.1.0版本测试。
内容的提问来源于stack exchange,提问作者Umakanth Pendyala
相关产品推荐
相关产品推荐

