You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Playwright点击按钮时触发TimeoutError问题求解

解决Playwright访问Facebook时的TimeoutError问题

问题代码

import asyncio
from playwright.async_api import async_playwright

async def fb():
  async with async_playwright() as p:
    browser = await p.chromium.launch(args=["--disable-gpu", "--single-process"])
    page = await browser.new_page()

    await page.goto('https://www.facebook.com/zuck')
    s = "#mount_0_0_Y4 > div > div:nth-child(1) > div > div:nth-child(5) > div > div > div.x9f619.x1n2onr6.x1ja2u2z > div > div.x1uvtmcs.x4k7w5x.x1h91t0o.x1beo9mf.xaigb6o.x12ejxvf.x3igimt.xarpa2k.xedcshv.x1lytzrv.x1t2pt76.x7ja8zs.x1n2onr6.x1qrby5j.x1jfb8zj > div > div > div > div.x92rtbv.x10l6tqk.x1tk7jg1.x1vjfegm > div";
    
    await page.locator(s).get_by_role("button").click(); # TimeoutError
    
    await browser.close()

if __name__ == "__main__":
  asyncio.new_event_loop().run_until_complete(fb())

运行环境

  • Docker基础镜像:mcr.microsoft.com/playwright/python:v1.41.0-jammy
  • Python版本:3.10.12
  • Playwright版本:1.41.2

报错堆栈

Traceback (most recent call last):
  File "/function/dbgq.py", line 20, in <module>
    asyncio.new_event_loop().run_until_complete(fb())
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/function/dbgq.py", line 15, in fb
    await page.locator(s).get_by_role("button").click(); # TimeoutError
  File "/function/playwright/async_api/_generated.py", line 15786, in click
    await self._impl_obj.click(
  File "/function/playwright/_impl/_locator.py", line 158, in click
    return await self._frame.click(self._selector, strict=True, **params)
  File "/function/playwright/_impl/_frame.py", line 494, in click
    await self._channel.send("click", locals_to_params(locals()))
  File "/function/playwright/_impl/_connection.py", line 63, in send
    return await self._connection.wrap_api_call(
  File "/function/playwright/_impl/_connection.py", line 495, in wrap_api_call
    return await cb()
  File "/function/playwright/_impl/_connection.py", line 101, in inner_send
    result = next(iter(done)).result()
playwright._impl._errors.TimeoutError: Timeout 30000ms exceeded.

解决方案

1. 替换脆弱的硬编码选择器

你使用的#mount_0_0_Y4是Facebook动态生成的ID,每次页面加载都会变化,根本无法稳定定位元素。改用语义化的定位方式:

  • 直接通过按钮角色和文本定位(根据实际按钮文本调整):
# 定位"关注"类按钮示例
await page.get_by_role("button", name="关注").click()
  • 优先使用元素的固定属性(如data-testid),比动态ID和层级选择器可靠得多。

2. 优化页面加载等待策略

Facebook是单页应用,默认的page.goto等待逻辑可能不适用,调整等待策略:

# 等待网络空闲后再继续,适配SPA加载特性
await page.goto('https://www.facebook.com/zuck', wait_until="networkidle")
# 先等待目标按钮可见,再执行点击操作
await page.get_by_role("button", name="关注").wait_for()
await page.get_by_role("button", name="关注").click()

3. 调整浏览器启动参数

--single-process参数会强制浏览器单进程运行,容易导致不稳定和加载异常,建议移除:

# 使用多进程模式启动浏览器
browser = await p.chromium.launch(args=["--disable-gpu"])
# 需要无头模式的话,显式设置headless=True(默认已开启)
# browser = await p.chromium.launch(headless=True, args=["--disable-gpu"])

4. 应对Facebook反爬机制

Facebook会检测自动化工具,可通过以下方式规避:

  • 设置真实浏览器的用户代理:
page = await browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
  • 使用持久化上下文保存登录状态,避免每次访问被拦截:
# 创建带存储状态的上下文
context = await browser.new_context(storage_state="fb_login_state.json")
page = await context.new_page()
# 首次运行时完成登录,保存状态到文件
# await page.goto("https://www.facebook.com/login")
# 登录后执行此代码保存状态
# await context.storage_state(path="fb_login_state.json")

5. 启用调试模式排查问题

通过Playwright调试工具直观查看页面状态:

# 启动可视化浏览器,查看页面加载和元素情况
browser = await p.chromium.launch(headless=False, args=["--disable-gpu", "--start-maximized"])
# 插入断点,暂停代码执行以检查页面
await page.pause()

可以直接确认页面是否加载完成、目标元素是否存在,以及是否有反爬拦截弹窗。


内容的提问来源于stack exchange,提问作者nemy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:55:11