Python 驱动浏览器自动化:Playwright 与 AI 集成实战
介绍 Playwright 在 Web 自动化领域的优势,对比 Selenium 等工具。涵盖异步并发最佳实践、Trace Viewer 调试、AI 视觉自愈脚本构建、反爬隐身技术及高性能集群部署方案。通过实战代码展示如何利用多模态模型实现元素定位及状态复用,提升自动化脚本的鲁棒性与执行效率。

介绍 Playwright 在 Web 自动化领域的优势,对比 Selenium 等工具。涵盖异步并发最佳实践、Trace Viewer 调试、AI 视觉自愈脚本构建、反爬隐身技术及高性能集群部署方案。通过实战代码展示如何利用多模态模型实现元素定位及状态复用,提升自动化脚本的鲁棒性与执行效率。

长期以来,Web 自动化工程师都在速度、稳定性和抗检测性之间做取舍:
ElementNotInteractableException。Playwright 的出现打破了这个僵局。作为微软开源的工具,它基于 CDP (Chrome DevTools Protocol) 但又不仅限于此,提供了跨浏览器(Chromium, Firefox, WebKit)的统一 API。
Playwright Script
Browser Server
Context 1 (Profile A)
Context 2 (Profile B)
Page 1
Page 2
time.sleep()。Playwright 会自动等待元素显式、可点击后再执行操作。在 Python 中,建议使用 async_playwright 来最大化性能。
import asyncio
from playwright.async_api import async_playwright
async def run():
async with async_playwright() as p:
# 启动浏览器(headless=False 可以看见界面)
browser = await p.chromium.launch(headless=False)
# 创建上下文(相当于隐身模式窗口)
context = await browser.new_context(
viewport={'width': 1920, 'height': 1080},
user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
)
page = await context.new_page()
await page.goto("https://example.com")
# 强大的选择器
# 文本定位
await page.click("text=Get Started")
# CSS + 文本混合
await page.click("button:has-text('Login')")
# XPath (不推荐,但支持)
await page.fill("//input[@name='username']", "admin")
# 截图保存证据
await page.screenshot(path="example.png")
await browser.close()
asyncio.run(run())
这是 Playwright 最核心的功能。通过录制 Trace,你可以事后回放整个脚本执行过程。
启用方式非常简单:
await context.tracing.start(screenshots=True, snapshots=True, sources=True)
# ... 执行操作 ...
await context.tracing.stop(path="trace.zip")
然后用 playwright show-trace trace.zip 即可可视化分析。
传统脚本最怕什么?前端改版。只要开发把 <button> 改成了其他标签,你的脚本就挂了。
当前,我们不需要手动修脚本,可以让 AI 来修。
如果选择器失效,我们可以抓取当前页面的截图,发给 GPT-4o 或 Gemini 1.5 Pro 这样的多模态模型,问它:'注册按钮在哪里?'
import base64
from openai import AsyncOpenAI
client = AsyncOpenAI(api_key="sk-...")
async def ai_smart_click(page, description):
""" 当常规选择器失败时,使用 AI 进行视觉定位点击 """
try:
# 1. 尝试常规模糊定位
await page.click(f"text={description}", timeout=2000)
except Exception:
print(f"常规定位失败,启动 AI 视觉定位:{description}...")
# 2. 截图
screenshot_bytes = await page.screenshot()
base64_image = base64.b64encode(screenshot_bytes).decode('utf-8')
# 3. 询问 VLM (Visual Language Model)
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": f"Locate the center coordinates (x, y) of the element described as '{description}' on this webpage screenshot. Return ONLY json like {{'x': 100, 'y': 200}}."},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
]
}],
response_format={"type": "json_object"}
)
coords = eval(response.choices[0].message.content)
()
page.mouse.click(coords[], coords[])
这种模式虽然比纯选择器慢(需要调用 API),但它极大地提高了脚本的鲁棒性。在关键业务流程(如支付下单)中,稳定性高于一切。
现在稍微像样点的网站都有 Bot 检测(Cloudflare, Akamai)。直接用 Playwright 可能会被识别为机器人。
网站会检查 navigator.webdriver 属性,或者检测 WebGL 指纹、字体列表等。
我们可以使用 playwright-stealth 库,或者手动注入 JS 来掩盖特征。
async def stealth_init(page):
await page.add_init_script("""
// 掩盖 webdriver 属性
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// 伪造 Chrome 插件列表 (如果是 headless 模式)
if (!navigator.plugins || navigator.plugins.length === 0) {
// ... 注入 Mock 数据
}
// 覆盖 WebGL 指纹
const getParameter = WebGLRenderingContext.prototype.getParameter;
WebGLRenderingContext.prototype.getParameter = function(parameter) {
if (parameter === 37445) { return 'Intel Inc.'; }
if (parameter === 37446) { return 'Intel Iris OpenGL Engine'; }
return getParameter(parameter);
};
""")
此外,最重要的技巧是保存状态(State Storage)。不要每次都重新登录,而是像真人一样复用 Cookies。
# 登录一次保存状态
await page.context.storage_state(path="state.json")
# 下次直接加载
context = await browser.new_context(storage_state="state.json")
当你需要每天抓取大量页面,单机单进程就不够看了。
结合我们之前讲的 asyncio,我们可以构建一个极致性能的爬虫集群。
async def worker(context, queue):
while True:
url = await queue.get()
page = await context.new_page()
try:
# 开启资源过滤,极大提升速度
await page.route("**/*.{png,jpg,jpeg,gif,css,font}", lambda route: route.abort())
await page.goto(url)
# ... 业务逻辑 ...
finally:
await page.close()
queue.task_done()
async def main():
queue = asyncio.Queue()
# 填充任务
for i in range(1000):
queue.put_nowait(f"https://example.com/item/{i}")
async with async_playwright() as p:
browser = await p.chromium.launch()
context = await browser.new_context()
# 启动 10 个并发 Worker 共享同一个浏览器实例(资源开销最小)
workers = [asyncio.create_task(worker(context, queue)) for _ in range(10)]
await queue.join()
这种共享 Browser Instance 但隔离 Page 的模式,比开启 10 个浏览器要节省 90% 的内存。
当前的 Playwright 已经不仅仅是一个测试工具,它是连接 AI 大脑与数字世界的桥梁。
未来的自动化不再是写死的脚本,而是能够感知、理解并自我修复的智能 Agent。
本文代码基于 Playwright Python 1.45+ 版本编写。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online