每天点后台,点导出,等验证码,切日期,再点一次“确认”,这种活干久了,人会先烦,代码反而还没写几行。
我后来基本不跟这种页面较劲了。尤其是那种“看起来有接口,实际请求里夹着 token、加密参数、奇怪跳转”的系统,硬扣接口经常半天过去还在抓包。这个时候我第一反应不是继续翻浏览器 network,而是直接上 Playwright。
这玩意我现在拿来干三类活:批量导报表、定时登录后台做检查、替人肉点点点的重复操作。一个字,省事。
先装上:
pip install playwrightplaywright install chromium很多人一上来就想研究目标系统的接口,我一般不急。先把流程跑通,证明这事能自动做,再考虑要不要往接口层收。因为不少内部系统写得很野,登录链路里掺着单点、跳转、验证码、前端混淆参数,拆接口不一定比“像人一样点页面”更快。
比如最常见的,登录系统后批量导出昨天的订单报表:
from pathlib import Pathfrom datetime import datetime, timedeltafrom playwright.sync_api import sync_playwrightDOWNLOAD_DIR = Path("downloads")DOWNLOAD_DIR.mkdir(exist_ok=True)yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")with sync_playwright() as p: browser = p.chromium.launch(headless=True) context = browser.new_context(accept_downloads=True) page = context.new_page() page.goto("https://oa.example.com/login") page.fill('input[name="username"]', "ops_robot") page.fill('input[name="password"]', "******") page.click('button:has-text("登录")') page.wait_for_url("**/dashboard") page.goto("https://oa.example.com/order/report") page.fill("#startDate", yesterday) page.fill("#endDate", yesterday) page.click('button:has-text("查询")') page.wait_for_selector("table tbody tr")with page.expect_download() as d: page.click('button:has-text("导出Excel")') download = d.value download.save_as(DOWNLOAD_DIR / f"order_{yesterday}.xlsx") print(f"[OK] 报表已下载: order_{yesterday}.xlsx") browser.close()这段代码没什么花活,但真能顶掉一大堆重复劳动。以前运营同学卡在页面上等导出,我这边丢到定时任务里,早上文件已经躺目录里了。
Playwright 还有个地方我挺喜欢:它不像有些自动化工具,跑着跑着就不知道死哪了。页面没加载、按钮没出来、文件没下完,它都有明确的等待机制。排障的时候也舒服,不是那种“脚本好像执行了,但又没完全执行”的玄学状态。
比如我一般会顺手加一层失败截图,出了问题直接看现场:
defsafe_click(page, selector, name):try: page.locator(selector).click(timeout=5000)except Exception as e: page.screenshot(path=f"error_{name}.png")raise RuntimeError(f"{name} 点击失败: {e}")别小看这张图。很多自动化脚本最后难维护,不是功能复杂,是报错信息太干。你只看到 timeout,根本不知道页面当时跳到哪了,是弹窗挡住了,还是按钮文案改了。留图,排查效率会高很多。
再往后一步,下载完文件通常还得清洗。这个时候 Python 的味道就出来了,浏览器自动化只是前半段,后半段交给脚本收尾:
import pandas as pddf = pd.read_excel(f"downloads/order_{yesterday}.xlsx")df = df[df["订单状态"] != "已取消"]df["支付时间"] = pd.to_datetime(df["支付时间"])df["金额"] = pd.to_numeric(df["金额"], errors="coerce").fillna(0)summary = ( df.groupby("渠道", as_index=False)["金额"] .sum() .sort_values("金额", ascending=False))summary.to_excel(f"downloads/summary_{yesterday}.xlsx", index=False)print("[OK] 汇总文件已生成")这一套连起来,基本就是:自动登录、自动查询、自动下载、自动清洗、自动汇总。以前半小时起步的活,现在变成几分钟,而且不用人盯着。
当然,Playwright 也不是没坑。
第一,定位别写太脆。不要满屏 nth-child,页面一改你就废了。优先找文本、表单 name、稳定的 data-testid。 第二,能复用登录态就别每次重新登,很多系统登录过程最慢。 第三,别一股脑 headless 跑到底。第一次调试我通常开可视化,页面怎么跳、按钮在哪、有没有遮罩,一眼就知道。 第四,真遇到验证码、短信校验这类东西,先别硬怼。该找系统开白名单开白名单,该换接口换接口,自动化不是跟安全策略对着干。
我现在看这种重复操作,第一眼已经不是“谁去做”,而是“这事能不能脚本化”。只要流程相对固定、输入规则清楚、结果能落文件,八成都能搞。
Playwright 不算什么玄学库,但它很像那种你一开始觉得“先手工也行”,真用起来之后就回不去的工具。尤其是做 Python 自动化,前面替你把网页这层麻烦吃掉,后面你再接 pandas、openpyxl、邮件通知,整条链路就顺了。