把华为云开发者成长中心的任务做成自动化:会话、组件与判定时机

举报
yd_255011313 发表于 2026/10/26 13:58:19 2026/10/26
【摘要】 华为云控制台自动化三层鉴权排障:MFA 提示页路由循环、SSO TGC 单次消耗、KooLabs 联邦登录与 auth-token 鉴权。

用浏览器自动化去跑成长中心这类任务平台,难点从来不是业务逻辑,而是三件事:会话为什么总掉、自研组件为什么点不动、任务什么时候才算完成。这三条都是踩出来的,记一下。

## 一、会话为什么总掉:TGC 是单次消耗品

华为云 SSO 的 `SSOTGC`(域 `auth.huaweicloud.com`)是会话级 cookie。它的行为很容易被误解:你以为它是一个可以反复用的"登录票据",实际上每次走 SSO 换 ticket 都会消费一次,多个浏览器上下文共享同一份 `storage_state` 时,先换到 ticket 的那个上下文会把 TGC 用掉,其他上下文再访问就会突然回落到"登录/注册",`document.cookie` 里 `SSOTGC` 直接消失。

我一开始的做法是每个脚本 `new_context(storage_state=...)`,跑几个脚本掉一次登录,反复触发短信验证,非常低效。

正确的做法是**持久化 profile + 常驻单进程**:

```python
ctx = p.chromium.launch_persistent_context(
r"C:\...\profile_sess", headless=True, locale="zh-CN",
args=["--disable-blink-features=AutomationControlled"])
page = ctx.pages[0]
```

cookie 落在 profile 目录里,进程不关就一直有效。实测隔两天重新拉起,仍然免验证码直接是登录态(日志里 `no sms dialog` / `LOGIN_RESULT=True`)。

再进一步,把"执行器"和"调度"拆开:常驻进程里跑一个任务循环,监听一个 `task.txt`,收到任务名就执行,结果写 `result.txt`。这样后续所有操作都在同一个会话里发生,彻底不会再有 TGC 被消耗的问题。

```python
for _ in range(240):
if os.path.exists(TASK_FILE):
task = open(TASK_FILE, encoding="utf-8").read().strip()
...
```

有个细节:**任务文件必须无 BOM 写入**。PowerShell 5.1 的 `Set-Content -Encoding UTF8` 会带 BOM,读出来变成 `\ufeffgrowth`,任务名匹配不上。用:

```powershell
$enc = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($path, 'growth', $enc)
```

## 二、自研组件为什么点不动

平台前端混着 ti3(tiny-vue)和老版 AngularJS,同一套点击策略常常一半有效一半无效。

**`get_by_text` 大面积超时**。ti3 的按钮结构是 `div.ti3-btn-item > div.ti3-btn-item-text`,文本在最内层 span 里,Playwright 的文本定位经常匹配到外层容器而判定为不可见。实测对 ti3 按钮用 `page.mouse.click(x, y)` 最稳:

```python
box = page.evaluate("""() => {
const bs = [...document.querySelectorAll('button')].filter(b =>
(b.innerText||'').trim() === '确定');
const r = bs[bs.length-1].getBoundingClientRect();
return {x: r.x + r.width/2, y: r.y + r.height/2};
}""")
page.mouse.click(box["x"], box["y"])
```

**复选框必须点击真实位置**。MFA 提示页那个"30 天不再提示"的 checkbox,`el.click()` 和 `dispatchEvent('change')` 都无效,必须 `mouse.click` 到它的 bounding box 中心,才能让 `is-disabled` 的"同意/下一步"按钮解禁。

**文件上传要区分两条路**。有的页面点击按钮弹出系统文件框,要用 `expect_file_chooser`;有的页面已经把 `input[type=file]` 渲染在 DOM 里(只是隐藏),直接 `set_input_files` 更省事:

```python
if page.locator('input[type="file"]').count():
page.locator('input[type="file"]').first.set_input_files(zip_path)
```

我遇到过一个反直觉的情况:`set_input_files` 之后**页面自己就把提交做完了**,不需要再点提交按钮。所以我之前一直以为"提交失败",实际早就成功了——表里已经出现提交时间、状态"评分中"。教训是:操作后先 dump 一次页面状态,别急着继续点下一步。

## 三、任务判定时机:提交即发分 vs 异步判定

这个坑最贵。赛事作品提交后我一直在等"审核通过",因为任务说明写着"上传作品成功且审核通过即可完成任务",所以就判定"短期做不到"。

实际行为是:**提交那一刻任务就点亮了**。表格显示提交时间,状态还在"评分中",但成长中心接口的 `is_finish` 已经是 1,100 分当场到账。

而另一类任务(比如"每周实践一个实验")是**异步判定**:实验环境建好、VPC 创建、结束实验,当时查 `is_finish` 还是 0,我连查三次都是 0 就误判失败了,二十分钟后再查已经变 1。

所以对判定时机要有预期差异:

- **提交类**(发文章、上传作品、报名活动):基本即时或分钟级;
- **行为类**(做实验、访问体验):可能十几分钟到半小时的延迟。

判断任务是否完成,不要靠"我刚才操作了没有",要靠轮询接口拿 `is_finish`,而且给它留够时间。

## 四、一条实用的排障顺序

遇到"点了没反应"时,我现在的固定顺序是:

1. 抓请求头,确认这步到底发没发请求;
2. 请求发了但报错 → 看错误码,很多"权限/缺参数"是业务侧校验;
3. 请求没发 → 元素定位问题,换坐标点击;
4. 坐标点击也没用 → 看是不是 disabled,往前找解禁条件(通常是某个复选框);
5. 全都不行 → 看页面有没有替代入口(比如同一个动作在别的接口上有 cookie 态通道)。

第三条和第四条帮我省了很多时间——自研组件的"不可见"和"禁用"看起来一样,其实是两类完全不同的问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。