方法论与洞察

自动化判据取结构不取文案

入档:2026-09-09 来源:给 aigc-topic-cover-factory skill 写小红书素材采集器(Playwright + 持久化登录态) 验证状态:⭐ 单案三处独立印证(登录墙误判 + 同域资源误收 + URL 参数空操作),三处全是跑真实目标才暴露的,单测无一能发现


一句话

自动化脚本判断「页面处于什么状态」「这条链接是不是我要的东西」时,认结构(DOM 元素、子域、扩展名),不要认文案字符串。文案是产品随时改的展示层,同一个状态往往有好几套说法;结构是前端组件契约,改动频率低一个量级。

更要命的是:文案判据出错时不会报错,而是静默地把垃圾当成果交出来。


三处实测

一、按文案判登录态,漏判成「已登录」

采集器要判断「登录态还在不在」。我写的判据是匹配页面上有没有「扫码登录」四个字。

实测页面写的是「手机号登录」。 结果:

logged_in? : True      ← 其实根本没登录
图片直链数 : 30        ← 全是 .js / .css / .ico,一张笔记图都没有

脚本兴高采烈地「成功」了,抓回 30 条前端静态资源。

正解:认结构——未登录时页面会盖一层 .login-container 遮罩,且 section.note-item 笔记卡片数为 0。这两个是组件契约,不随文案改。

def is_logged_in(page):
    if page.locator(".login-container").count() > 0:
        return False
    if page.locator("section.note-item, div.note-item").count() > 0:
        return True
    return True

二、同域名 ≠ 同类资源

我用正则扫 HTML 找 xhscdn.com 收图片链接。但同一个域名下混着两类完全不同的东西:

子域装的是要不要
fe-static.xhscdn.com.js / .css / .svg 前端构建产物
fe-video-qc.xhscdn.com.ico / .js
sns-webpic-*.xhscdn.com笔记正文图
sns-avatar-*.xhscdn.com头像

正解:两道结构判据叠加——① 读渲染后 img 元素的 currentSrc(而不是正则扫 HTML,扫 HTML 会把内联脚本里的资源链接一并捞进来);② 按子域前缀 + 扩展名白名单过滤。

三、参数「写了」不等于「生效」(2026-09-10 追加)

采集器里有个 upgrade_url(),把直链的 imageView2/2/w/360 重写成 w/1280,我一直以为它在提分辨率。

实测:它是个彻底的空操作。 搜索列表页的直链形如

.../notes_uhdr/<id>!nc_n_webp_mw_1

尺寸由末尾 ! 后的 CDN 预设 决定,imageView2 查询参数被完全忽略——w/1280w/1920、 把参数全删掉,返回的都是同一张 640×853。而换预设后缀(!nd_dft_wlteh_webp_3 等)一律 403: 路径里带时间 + 哈希令牌,签名和预设是绑死的。

这是本文那条律的第三处印证,而且是最隐蔽的一种:前两处是「判据看错」,这处是 「动作根本没发生,但没有任何东西报错」。参数写上去了、代码跑过了、图也下下来了, 唯一的破绽是分辨率——如果我没去核对返回图的尺寸,这个函数可以永远躺在那儿假装工作。

校验的落点不是「有没有报错」,是**「返回的东西长什么样」**。改了参数就去比对改前改后的产物, 一样就说明参数没生效。

(结论:640 宽对 960×600 输出够用——文字在 1920px 画布上矢量绘制再降采样,锐度不受影响, 背景略软反而贴「真实手机照」的调性。要原图得逐条进笔记详情页取,不划算。)


为什么文案判据必然烂


推论一:装完依赖立刻跑一次真实目标

这三处单测全都发现不了——我自己造的假 URL 全部「通过」,因为造数据时脑子里就是那个错误的模型。是装完 Playwright 跑了一次真实搜索页,才把 30 条垃圾链接打到脸上;分辨率那处更晚,是去核对返回图尺寸才露馅。

依赖装完不是终点,是第一次能做真实验证的起点。别装完就宣布完成。

同族参见 用错度量会给出虚假通过_v1

推论二:留「零结果」告警,别静默成功

结构类名也会变(前端重构就会)。所以判据之外还得有一道兜底:

if not urls:
    print("! 一张笔记图都没取到。要么关键词太偏,要么登录态刚失效。", file=sys.stderr)

最危险的不是失败,是拿着垃圾数据宣称成功。 任何「本该有结果却拿到 0 条」的路径,都要吵出来。


如何使用

写任何页面自动化(采集 / 发布 / 巡检)时,先问三句:

  1. 我判断状态用的是文案还是结构?是文案就换掉。
  2. 我筛资源用的是域名还是子域 + 类型?同域混装是常态。
  3. 零结果这条路径,我是吵出来了,还是静悄悄当成功了?
  4. 我改的那个参数,核对过改前改后的产物有没有变吗?没变就是没生效。

然后:装完依赖,立刻对真实目标跑一次,看回来的东西长什么样,而不是看有没有报错。


关联文档

类型/协作工具链