Selenium 装驱动太麻烦Playwright 入门指南Python 网页自动化新标准一、开头痛点驱动、等待、玄学报错做过网页自动化的同学大概率被这三件事折磨过装驱动chromedriver的版本必须和本机 Chrome 严丝合缝浏览器一自动升级脚本第二天就SessionNotCreatedException。等元素页面还没渲染完就find_element报NoSuchElementException于是满屏time.sleep(3)慢且不稳。换浏览器Selenium 要分别配 Chrome、Firefox、Edge 的驱动环境一换全得重来。Playwright 把这三点一次性解决了自带浏览器一条命令下载版本永远匹配、操作自带自动等待不用手写 sleep、一套 API 通吃 Chromium / Firefox / WebKit。它由微软团队维护Python 版 API 设计得很干净写起来比 Selenium 顺手不少。二、环境准备两条命令Playwright 支持 Python 3.8。同样建议用虚拟环境隔离python-mvenv .venvsource.venv/bin/activate# Windows 用 .venv\Scripts\activate# 第一步装 Python 包pipinstallplaywright# 第二步下载浏览器内核约 100~300MB只需执行一次playwrightinstallchromium第二步是很多新手卡住的地方——它下载的是 Playwright 自带的浏览器不是你桌面上那个 Chrome所以不存在版本对不上的问题。国内下载慢可以走镜像# 使用国内镜像加速下载PLAYWRIGHT_DOWNLOAD_HOSThttps://cdn.npmmirror.com/binaries/playwright playwrightinstallchromium验证安装# check_env.pyfromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:browserp.chromium.launch(headlessTrue)pagebrowser.new_page()page.goto(https://example.com)print(页面标题,page.title())browser.close()能打印出Example Domain就说明环境没问题。三、最小可运行示例打开页面并截图Playwright 有同步和异步两套 API日常脚本用同步版最省心# shot.pyfromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:# headlessTrue 表示无界面运行调试时改成 False 能看到真实浏览器browserp.chromium.launch(headlessTrue)pagebrowser.new_page(viewport{width:1280,height:800})page.goto(https://www.python.org/)# full_pageTrue 会截取整页长图不只是可视区域page.screenshot(pathpython_org.png,full_pageTrue)browser.close()对比 Selenium同样的功能少了驱动配置、少了显式等待代码块从十几行压到十行以内。四、核心概念Locator、自动等待、上下文4.1 Locator定位元素的新写法Playwright 推荐用locator()拿到元素句柄所有操作都基于它# 下面几种写法等价选你顺手的page.locator(button#submit).click()page.locator(text登录).click()page.get_by_role(button,name登录).click()# 按语义角色最稳page.get_by_placeholder(请输入用户名).fill(admin)page.get_by_text(下一步).click()Locator 是惰性的写page.locator(...)时不会真的去查 DOM只有执行.click()、.fill()时才查找并且会自动等到元素可见、可点击、不被遮挡。这就是「自动等待」。4.2 自动等待和 time.sleep 说再见fromplaywright.sync_apiimportexpect# 断言元素可见默认超时 5 秒期间反复重试expect(page.get_by_text(提交成功)).to_be_visible(timeout10000)# 断言 URL 变化expect(page).to_have_url(https://example.com/dashboard)expect是 Playwright 官方的断言工具比assert page.title() ...更可靠因为它会轮询等待而不是一次性判断。需要改全局超时可以这样page.set_default_timeout(15000)# 所有操作默认最多等 15 秒4.3 上下文多开互不干扰的会话context相当于一个独立的浏览器会话独立的 Cookie、缓存比开多个 browser 省资源withsync_playwright()asp:browserp.chromium.launch()# 模拟移动端 中文环境ctxbrowser.new_context(viewport{width:390,height:844},user_agentMozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15,localezh-CN,)pagectx.new_page()page.goto(https://example.com)ctx.close()# 关上下文Cookie 一起清掉browser.close()五、进阶用法表单、上传、拦截5.1 填表单与键盘鼠标page.get_by_label(用户名).fill(zhangsan)page.get_by_label(密码).fill(secret123)page.get_by_label(记住我).check()page.get_by_role(combobox).select_option(beijing)page.keyboard.press(Enter)5.2 文件上传与下载# 上传直接给本地路径不用再找系统文件框page.set_input_files(input[typefile],report.xlsx)# 下载必须用 expect_download 包住触发动作withpage.expect_download()asdl:page.get_by_text(导出报表).click()downloaddl.value download.save_as(data/export.xlsx)5.3 拦截请求屏蔽图片提速抓数据时图片、字体往往没用直接拦掉能明显加速defblock_images(route):ifroute.request.resource_typein(image,font,media):route.abort()else:route.continue_()page.route(**/*,block_images)page.goto(https://news.example.com)六、实战场景自动登录并抓取列表完整代码下面这个例子把上面几点串起来带登录态抓取分页数据并保存截图# crawl_demo.pyfromplaywright.sync_apiimportsync_playwright,expect BASEhttps://example.comdefmain():withsync_playwright()asp:browserp.chromium.launch(headlessTrue)ctxbrowser.new_context(localezh-CN)pagectx.new_page()page.set_default_timeout(15000)# 1. 登录page.goto(f{BASE}/login)page.get_by_label(账号).fill(your_account)page.get_by_label(密码).fill(your_password)page.get_by_role(button,name登录).click()# 等到跳转完成不要用 sleepexpect(page).to_have_url(f{BASE}/dashboard)# 2. 抓多页列表rows[]forpage_noinrange(1,4):page.goto(f{BASE}/items?page{page_no})expect(page.locator(.item-row).first).to_be_visible()itemspage.locator(.item-row).all()foritinitems:rows.append({title:it.locator(.title).inner_text(),price:it.locator(.price).inner_text(),})print(f第{page_no}页抓到{len(items)}条)# 3. 保存登录态下次直接复用省掉重复登录ctx.storage_state(pathauth.json)print(共抓取,len(rows),条)browser.close()if__name____main__:main()下次运行时直接加载已保存的登录态ctxbrowser.new_context(storage_stateauth.json)七、和 Selenium 怎么选维度PlaywrightSelenium浏览器驱动自带一条命令安装需手动下载、版本必须匹配等待机制操作自带自动等待需自己写 WebDriverWait 或 sleep多浏览器一套 API 支持 Chromium/Firefox/WebKit每个浏览器各自适配录制脚本playwright codegen官方支持依赖第三方插件网络拦截原生page.route需借助代理生态与资料较新中文资料相对少十年积累资料最多、岗位要求常见结论新项目优先 Playwright效率和稳定性都更好老项目或需要兼容既有 Selenium 资产的继续用 Selenium两者并不互斥。八、常见坑与解决办法1playwright install卡住或超时换国内镜像见第二节。公司网络有代理时设置HTTPS_PROXY环境变量再执行。2locator.click()超时先确认是不是在 iframe 里。跨框架要先切进去framepage.frame_locator(iframe#login-frame)frame.get_by_role(button,name登录).click()3被网站识别为自动化默认 headless 会带自动化特征可以加启动参数缓解browserp.chromium.launch(headlessTrue,args[--disable-blink-featuresAutomationControlled],)4抓到的中文乱码确认new_context(localezh-CN)并且写入文件时指定编码encodingutf-8Windows 上尤其容易踩。5调试时看不到过程打开录制事后回看每一步ctx.tracing.start(screenshotsTrue,snapshotsTrue)# ... 你的操作 ...ctx.tracing.stop(pathtrace.zip)用playwright show-trace trace.zip可以在浏览器里逐步回放。九、总结与下一步Playwright 的三个核心优势自带浏览器告别驱动地狱、自动等待告别满屏 sleep、统一 API一套代码跑三种内核。如果你之前被 Selenium 的驱动和等待折腾过换过来基本是纯收益。下一步建议用playwright codegen https://你的目标站点录一遍看看官方推荐的选择器怎么写把现有脚本里的time.sleep逐步替换为expect(...)断言需要并发时改用异步 APIfrom playwright.async_api import async_playwright配合asyncio.gather。官方文档https://playwright.dev/python/docs/intro