WorkBuddy开始出现幻觉了?
一、拾枝杂谈
WorkBuddy出现幻觉了。
百家号的后台统计字段有六个,分别是“阅读量”,“评论量”,“点赞量”,“收藏量”,“分享量”,和 “分润和赞赏收益”。如下图所示:

但是当 WorkBuddy 通过脚本去收集我的文章数据时,居然把第一个字段“猜成”了 “推荐量”。
我们知道在大部分平台中,“推荐量” 或者 “展现量” 只是平台给的曝光量,就是别人看到你的文章的次数,但是别人看到了不一定会真的点进去看,“阅读量”才是表示后者的字段。更何况,百家号这个平台压根没有“推荐量”这个字段。
真是匪夷所思,要知道 WorkBuddy 是通过 Playwright 进行数据爬取的,而 Playwright 是不依靠“视觉”来分析页面结构的,那它这么会“猜错”呢?
二、销声匿迹
我随即向 WorkBuddy 表达了我的不满,并且询问它到底是怎么回事。
WorkBuddy 也比较干脆,直接写了个脚本把百家号后台的 DOM 抓出来看了一篇。原来不是Playwright做不到,而是字段名本来就不在静态 DOM 里面,而且 WorkBuddy 之前写的脚本也没有触发 tooltip(就是把鼠标悬停到图标上面查看提示),所以只能猜。又因为之前已经打通的平台都有类似于“推荐量”的机制,所以WorkBuddy就想当然的把第一个字段猜成了“推荐量”,即便它的真实名是“阅读量”。

后台单条文章的卡片大致是下面这样:
<div class="client_pages_content_v2_components_data2action_commonData fl">
<span class="wrap fl">
<div class="count-item"><img src="...a9b8fabe...svg+xml" alt=""><div>0</div></div>
<div class="count-item"><img src="...cf23af3d...svg+xml" alt=""><div>0</div></div>
<div class="count-item"><img src="...273e35d0...svg+xml" alt=""><div>0</div></div>
<div class="count-item"><img src="...39e1e4b3...svg+xml" alt=""><div>0</div></div>
<div class="count-item"><img src="...0e88c6d9...svg+xml" alt=""><div>0</div></div>
<div class="count-item"><img src="...income.svg" alt=""><div>0</div></div>
</span>
</div>
可以看到,单篇文章对应的div里面,有六个count-item子div,每个count-item对应一个字段,所以共六个字段,但是每个count-item里面只有一个<img>图标和一个<div>数字,除此之外就没了,甚至<img>里面的alt, title, aria-label这些属性也都是空的,没有任何的文字标签。
WorkBuddy 还告诉我,周围的 DOM 文本里面也没有阅读量、评论量这类的字眼,只能拿到纯数字序列。所以如果只是用 Playwright 去读取 innerText 或者 就是简单地去遍历 DOM 属性,我们能看到的就是 6 个数字,但我们不知道它们分别代表什么。
三、狡兔三窟
那问题来了:字段名到底在哪儿?
WorkBuddy 写得脚本模拟了 hover(悬停) 过程,最终发现字段名只出现在 鼠标悬停到图标上之后弹出的 tooltip 组件里面。也就是说,百家号后台的真实字段名是通过 JS 动态渲染到 tooltip 组件里的,而不存在于初始 HTML 中。
Playwright 要想拿到这些字段名,必须先找到这六个<img>图标,并依次模拟鼠标悬停行为,触发 tooltip,然后再读取 tooltip 文本。只不过最开始写得脚本里面没做这件事,毕竟 WorkBuddy 也没想到一个字段名藏得这么深,所以WorkBuddy只能瞎猜了。
在没有标签的情况下,WorkBuddy 只能依靠“经验”推断可能的字段名,再加上文章卡片上本身就有“已推荐”标签,所以 WorkBuddy 认为“推荐量”看起来是个合理的默认猜测。但也只是猜测,DOM 本身并没有证实或证伪它,直到我人工 hover 后,告诉了它真实字段顺序,它才知道第 1 个其实是“阅读量”。
四、瓜熟蒂落
在明白了 WorkBuddy “幻读” 的原因后,WorkBuddy 并没有改成“读tooltip”的字段,因为需要 hover 每个图标读取 tooltip,虽然能拿到真实字段名,但是实现更复杂。
WorkBuddy 最终选择了“直接按固定位置”读取前5个数字,这样最简单、稳定、而且不依赖 tooltip。代码写成了:
const stats = allNums.slice(0, 5); // 取前 5,跳过第 6 个收益
这个函数表示从这个数组的第 0 个元素开始取,取到第 5 个元素之前(不包含第 5 个),正好6个字段。
那如果百度哪天把顺序调了怎么办?
那是后面的事情,先过好当下吧。
更多推荐
所有评论(0)