找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4522

积分

0

好友

632

主题
发表于 1 小时前 | 查看: 2| 回复: 0

每天登录后台、点导出、等验证码、切日期、再点“确认”,这种重复操作干久了,人先烦,代码反而还没写几行。后来我基本不跟这种复杂页面较劲了,特别是那些“看起来有接口,实际请求里夹着 token、加密参数、奇怪跳转”的内部系统。硬着头皮去破解接口,经常半天过去还在抓包。遇到这种情况,我现在的第一反应不是继续翻浏览器的开发者工具,而是直接启用 Playwright

我现在主要拿它来处理三类事情:批量导报表、定时登录后台巡检、替代人肉点击的重复操作。就一个字:省事。

首先,安装它:

pip install playwright
playwright install chromium

很多人一上来就钻研目标系统的接口,我倒觉得不急。先把流程用自动化脚本跑通,证明这件事能做,再考虑要不要往底层接口层优化。因为不少内部系统的登录链路掺杂着单点登录、页面跳转、验证码、前端混淆参数,拆解接口付出的时间,未必比“模拟真人点击页面”更少。

比如,一个最常见的场景:登录系统后台,批量导出昨天的订单报表。

from pathlib import Path
from datetime import datetime, timedelta
from playwright.sync_api import sync_playwright

DOWNLOAD_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 的另一点是:它不像某些自动化工具,跑着跑着就“失联”了。无论是页面没加载完、按钮没出现、还是文件没下载完毕,它都提供了明确的等待机制。排障时体验也好很多,不再是那种“脚本好像执行了,但又没完全执行”的玄学状态。

我通常会顺手加一层失败截图功能,出了问题能直接“看到”现场:

def safe_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}")

别小看这一张截图。很多自动化脚本最后变得难以维护,不是因为功能复杂,而是因为报错信息太干瘪。你只看到一个超时错误,根本不知道页面当时跳转到哪里了,是弹窗遮住了按钮,还是按钮的文案被产品经理改了。保留出错时的现场截图,排查效率会高很多。

流程再往后走一步。下载完的报表文件通常还需要清洗和汇总,这时候 Python 数据处理的能力就派上用场了。浏览器自动化只是解决了“拿到数据”的前半程,后半程可以交给 pandas 这类库来优雅收尾:

import pandas as pd

df = 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 这类测试属性。

第二,能复用登录状态就别每次都重新登录。很多系统的登录过程(包括可能存在的二次验证)是最耗时的环节。

第三,别一上来就用无头模式跑到底。第一次编写和调试脚本时,我通常会打开可视化模式,这样页面如何跳转、按钮在哪里、有没有意外的弹窗遮罩,都能一目了然。

第四,如果真遇到了验证码、短信验证这类强安全校验,先别硬刚。该找系统负责人开通白名单就去申请,该评估是否有更稳定的内部接口就去沟通。自动化的目的是提升效率,而不是和安全策略正面冲突。

我现在看待这类重复性操作,第一反应已经不是“该谁去做”,而是“这个流程能否脚本化”。只要流程相对固定、输入规则明确、输出结果能落地成文件,八成都能用自动化搞定。

Playwright 算不上什么高深莫测的库,但它很像那种你一开始觉得“先手工对付一下也行”,真正用顺手之后就再也回不去的工具。尤其在 Python 自动化生态里,它在前端帮你把“模拟浏览器操作”这层最麻烦的事情处理掉,后面你再无缝衔接 pandasopenpyxl,或者加上邮件通知,整条数据处理链路就变得非常顺畅。如果你也在为类似的后台操作烦恼,不妨试试这个思路,或许能在 云栈社区 找到更多同路人的实战经验。




上一篇:实习月薪600元引发的思考,顺便聊聊LeetCode单调栈解法
下一篇:Moonshot AI Kimi 考虑赴港上市,或成 AI 赛道港股第一股,估值达 180 亿美元
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-28 08:43 , Processed in 0.789848 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表