Playwright Python脚本本地正常,部署AWS Lambda后超时故障排查
问题背景
开发的Playwright脚本在本地使用无头浏览器可正常运行,但部署到AWS Lambda后函数超时,自动化流程无法完成。脚本部署在包含Lambda处理器和Lambda层的Docker镜像中,内部中间件系统运行正常,多数自动化任务在本地Linux机器上也能完美执行,但涉及地理定位的网站自动化脚本在Lambda中失效。
环境详情:
- AWS Lambda运行时:Python 3.9
- Playwright版本:1.35.0
- AWS区域:ap-south-1
相关代码:
async def run(self) -> None: async with async_playwright() as playwright: lead_create_status = "not_created" lead_id = "null" custom_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" identifier_logger = self.logger_generator.get_logger(YesBankCc.IDENTIFIER) browser = await playwright.chromium.launch(headless=True, args=["--single-process"]) wait_until = "load" # context = await browser.new_context(user_agent=custom_user_agent, # geolocation={"longitude": 72.877655, "latitude": 19.075983}, # permissions=["geolocation"]) geolocator = Nominatim(user_agent="MyApp") location = geolocator.geocode("Mumbai") print("The latitude of the location is: ", location.latitude) print("The longitude of the location is: ", location.longitude) context = await browser.new_context( ignore_https_errors=True, # java_script_enabled=True, user_agent=custom_user_agent, viewport={"width": 1920, "height": 1080}, geolocation={"longitude": location.longitude, "latitude": location.latitude}, permissions=["geolocation"], ) identifier_logger.debug("New context created...") page = await context.new_page() page.set_default_timeout(120000) identifier_logger.debug("New page created...") # Navigate to login page identifier_logger.debug("Navigating to login page...") await page.goto(url=self._portal_info["crm_url"], wait_until="load") print(f'URL = {self._portal_info["crm_url"]}') identifier_logger.info("Successfully navigated to login page") identifier_logger.debug("Filling in login details...") await sleep(10) identifier_logger.debug("Waited for 10 seconds") identifier_logger.debug("Going to click mobile number field") await page.locator('[id="username"]').click() # await page.get_by_placeholder('Enter Mobile Number').click() identifier_logger.debug("Clicked enter mobile number field") await page.locator('[id="username"]').fill(value=str(self._portal_info["crm_username"])) # await page.get_by_placeholder('Enter Mobile Number').fill(value=str(self._portal_info["crm_username"])) identifier_logger.debug("Filled enter mobile number field") await page.wait_for_load_state('domcontentloaded') await page.locator( '[class="btn-primary btndisable mat-button mat-button-base ng-star-inserted"]').click() identifier_logger.debug("Send OTP button clicked") identifier_logger.debug("Login OTP Sent successfully..."
问题列表
- 在AWS Lambda中使用Playwright相比本地环境有哪些已知限制或差异?
- 导致Lambda函数超时的原因是什么,如何排查并解决?
- 部署Playwright代码到AWS Lambda时需要注意哪些特定配置或事项?
问题解答
1. AWS Lambda使用Playwright的限制与差异
- 资源配额限制:Lambda有严格的资源上限,包括内存(128MB-10GB)、CPU(与内存绑定,内存越高CPU性能越好)、临时存储(/tmp目录最大512MB)、执行时间(最长15分钟)。本地环境资源充足,Playwright渲染页面需要的内存、CPU资源在Lambda中可能受限,导致运行缓慢或卡死。
- 网络环境差异:Lambda若部署在VPC内,需配置NAT网关、安全组才能访问公网;本地网络通常无此类限制。此外Lambda的出口IP动态变化,可能被目标网站的反爬机制拦截。
- 系统环境差异:Lambda基于Amazon Linux 2,与本地Linux发行版的系统依赖库、字体环境不同,Playwright依赖的Chromium可能因缺少依赖(如字体、图形库)出现渲染异常。
- 浏览器运行模式限制:Lambda的容器环境权限有限,Chromium的沙箱模式默认无法正常运行;强制使用
--single-process参数会破坏Chromium的多进程架构,导致稳定性下降、内存泄漏。 - 临时存储特性:Lambda的/tmp目录是临时存储,函数重启后会清空,Playwright的缓存、临时文件存放在此处,若空间不足会引发错误。
2. 超时原因排查与解决
可能原因
- 网络阻塞:Lambda无法访问Nominatim地理编码服务或目标CRM网站,或请求超时;代码中
geolocator.geocode("Mumbai")是同步调用,未设置超时,可能无限阻塞。 - 资源不足:Lambda内存配置过低,Chromium渲染页面时内存不足,导致页面加载缓慢或进程卡死。
- 元素定位失败:Lambda环境下页面渲染与本地存在差异,元素选择器失效,导致Playwright等待元素超时(如按钮处于不可点击状态时触发点击操作)。
- 无效等待:代码中使用
await sleep(10)固定等待,浪费时间且无法适配页面实际加载速度。 - 浏览器参数不合理:
--single-process参数在Lambda环境下稳定性差,导致浏览器启动慢或崩溃。
排查步骤
- 查看CloudWatch日志,确认最后一条日志输出位置,定位超时发生的阶段(地理编码、页面加载、元素操作等)。
- 增加关键节点日志(如地理编码请求前后、页面跳转前后),细化问题范围。
- 在Lambda中测试网络连通性:添加代码测试Nominatim和CRM网站的访问响应时间。
- 临时调高Lambda内存配置(如至1GB),验证是否因资源不足导致超时。
解决方法
- 给地理编码请求添加超时:
geolocator.geocode("Mumbai", timeout=10),避免无限等待。 - 替换固定等待为Playwright原生等待:如
await page.wait_for_selector('[id="username"]', state="visible"),替代await sleep(10)。 - 优化浏览器启动参数:移除
--single-process,添加--no-sandbox、--disable-dev-shm-usage、--disable-gpu等适配Lambda环境的参数。 - 调整Lambda配置:将内存设置为512MB以上,超时时间根据流程长度调整(最长15分钟)。
- 检查VPC配置:若Lambda在VPC内,确保安全组允许出站访问80/443端口,配置NAT网关实现公网访问。
- 替换同步地理编码调用:改用异步请求(如aiohttp调用Nominatim API),避免阻塞Playwright的异步事件循环。
3. 部署Playwright到Lambda的注意事项
- 环境适配:基于Lambda官方Python 3.9镜像构建Docker镜像,在镜像中执行
playwright install chromium --with-deps,确保安装Amazon Linux 2兼容的Chromium及依赖库。 - 资源配置:Lambda内存至少设置为512MB,推荐1GB以上;超时时间根据自动化流程的实际耗时设置,避免过短导致超时。
- 网络配置:若需访问公网,优先选择将Lambda部署在VPC外;若必须在VPC内,需配置NAT网关和对应的安全组规则。
- 浏览器参数优化:启动Chromium时添加
--no-sandbox、--disable-dev-shm-usage、--disable-setuid-sandbox、--disable-gpu参数,适配Lambda的容器环境。 - 日志与监控:开启CloudWatch日志,在关键步骤添加详细日志;使用AWS X-Ray追踪请求流程,定位性能瓶颈。
- 避免同步阻塞:所有外部请求(如地理编码)需改用异步方式,避免阻塞Playwright的异步事件循环,拖慢整体流程。
- 临时存储管理:避免在/tmp目录存储大量文件,必要时清理临时文件,防止空间不足。
内容的提问来源于stack exchange,提问作者Mohanraj M
相关产品推荐
相关产品推荐

