为了修改封面图高度折腾了一晚上,Workbuddy模型由Space-Bunny转Deepseek4.1flash终于给修好,还生成了个Skill.md,给大家参考参考。
name: webpage-render-measure
description: 当浏览器自动化工具(agent-browser 等)在本机起不来、或「CSS 明明写了却不生效」「元素尺寸不对」这类问题时,用本机已有的 Chromium 通过 Chrome DevTools Protocol 精确测量网页元素的真实渲染尺寸与生效样式,并能整页截图。也含「Typecho 主题/插件通过 FTP 部署」的完整流程与命名规则。
agent_created: true
网页真实渲染测量(CDP 直连)
什么时候用
- 用户说「CSS 改了没效果」「元素太大/太高/位置不对」,需要知道元素实际渲染成什么样
- 需要知道到底是哪条 CSS 规则生效了(而不是靠推测)
- agent-browser 或其它浏览器自动化工具的守护进程在本机起不来(Windows 上常见,报 SIGTERM 无输出)
需要给页面截图看效果
核心原则:先实测,再动手改。 不要在没看到实际渲染值的情况下反复改代码然后让用户上传试错。
前提:找到 Chromium
agent-browser 起不来不代表没有浏览器。Playwright 装的 Chromium 通常还在:
ls "C:/Users/ASUS/AppData/Local/ms-playwright/" # 看有哪些版本目录
find "C:/Users/ASUS/AppData/Local/ms-playwright/chromium-*/" -name "chrome.exe" | head -3典型路径:
C:\Users\ASUS\AppData\Local\ms-playwright\chromium-1234\chrome-win64\chrome.exe
也可以用系统自带的 Edge(Windows 必有):
C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
方法一:整页截图(最简单)
CHROME="C:/Users/ASUS/AppData/Local/ms-playwright/chromium-1234/chrome-win64/chrome.exe"
"$CHROME" --headless --disable-gpu --no-sandbox --hide-scrollbars \
--window-size=1440,2400 --virtual-time-budget=15000 \
--screenshot="C:/path/out.png" "https://example.com"
- --virtual-time-budget=15000 给 JS 和图片 15 秒加载时间,必须加,否则截图是空的
- 截图后用 Read 工具直接查看(能看图)
- --window-size 高度给大一点可以看到整页
- 输出 wsalookup 之类的 stderr 报错可以忽略
方法二:精确测量(关键武器)
用 --remote-debugging-port 启动,通过 CDP 发 JS 拿真实渲染值。
重大便利:Node 22 内置了全局 WebSocket,所以不需要 playwright 等任何依赖。
见 scripts/measure.js(可直接改 URL 使用)。核心步骤:
- spawn 启动 Chrome,带 --headless --remote-debugging-port=9333
- 轮询 http://127.0.0.1:9333/json 直到拿到 target
- 用 new WebSocket(target.webSocketDebuggerUrl) 连上
- 发 Page.enable / Runtime.enable / Page.navigate
- sleep(8000~9000) 等图片和 JS 加载完(关键,不等就是拿到加载前的值)
- Runtime.evaluate 跑 JS,取回 getBoundingClientRect() + getComputedStyle()
- 结束后 ws.close() + child.kill()
测量脚本要抓什么
// 元素真实渲染尺寸
var r = el.getBoundingClientRect();
r.width, r.height
// 生效的计算样式
var cs = getComputedStyle(el);
cs.height, cs.maxHeight, cs.position, cs.objectFit, cs.overflow
// 图片原始尺寸(判断是不是图片本身太大)
img.naturalWidth, img.naturalHeight, img.complete
// 有没有内联样式在捣乱
img.getAttribute('style')
// 列出所有匹配的选择器及其声明 —— 定位"哪条规则真的生效"
for (sheet of document.styleSheets)
for (rule of sheet.cssRules)
if (rule.selectorText.includes('目标类名'))
rule.selectorText, rule.style.height, ...模拟手机视口
await send('Emulation.setDeviceMetricsOverride',
{ width: 390, height: 800, deviceScaleFactor: 1, mobile: true });
await send('Page.navigate', { url });
await sleep(8000);
坑
不等加载就测 → 拿到加载前的值(图片未加载时尺寸是 0 或占位值)
- Node 版本:WebSocket 是 Node 22 才有的全局变量。用旧 Node 会报 WebSocket is not defined
- Chrome 每次启动需要 1~3 秒,轮询要留够次数(25 次 × 600ms)
- Emulation.setDeviceMetricsOverride 之后要重新 Page.navigate 才生效
常见真凶对照表
现象
检查什么
CSS 规则看着完全正确、优先级也对,但不生效
选择器方向写反了。把类加在
元素比预期高/大
先看 cs.height 实际值;再看容器和内容的 getBoundingClientRect()
图片撑开容器
看 naturalWidth/naturalHeight。图片本身是竖版大图时,仅限制容器高度不够,要 position:absolute + object-fit:cover 让它脱离文档流
改了没效果
看资源 URL 有没有 ?v= 版本号;没有就是缓存问题
配套:Typecho 主题/插件的 FTP 部署
命名规则(Typecho 1.2/1.3,最容易踩的坑)
Typecho 按文件夹名拼出期望的类名:
// var/Typecho/Plugin.php 的 portal()
$className = "\\" . PLUGIN_NAMESPACE . "\\{$pluginName}\Plugin";
// 即 \TypechoPlugin\<文件夹名>\Plugin
规则:文件夹名必须严格等于类名约定,不能加 _1.2、_v3、-master 之类后缀。
插件正确结构:
<?php
namespace TypechoPlugin\Xxx; // Xxx 必须等于文件夹名
use Typecho\Plugin\PluginInterface;
class Plugin implements PluginInterface
{
public static function activate(): string { ... }
public static function deactivate(): string { ... }
public static function config(Form $form) { ... }}
- 不要用老接口 Typecho_Plugin_Interface(1.2+ 已移除)
- 插件文件省略结尾 ?> 是标准做法
- 类名对不上 → 后台点启用报「无法启用插件」或直接 500
FTP操作
列目录
curl -s -u "用户名:密码" "ftp://主机/路径/" --list-only
下载
curl -s -u "用户名:密码" "ftp://主机/路径/文件" -o 本地文件
上传
curl -s -u "用户名:密码" -T 本地文件 "ftp://主机/路径/文件" -w "%{http_code}\n"
成功返回 226
- 常见虚拟主机根目录是 /wwwroot(不一定是 /www)
- Typecho 根:/wwwroot/ 下有 var、usr、admin、index.php、config.inc.php
- 主题在 /wwwroot/usr/themes/<主题名>/
- 插件在 /wwwroot/usr/plugins/<插件名>/
- 改文件前先把服务器原文件下载备份
交付完整主题包
给用户上传用的包要给完整主题(可直接整体覆盖),不要只给改动的几个文件。用 Node 手写 zip 时注意:
- local header 和 central directory 的 flags 都要设 0x0800(UTF-8 文件名),否则中文文件名乱码
- 排除 .bak、.DS_Store、__MACOSX、.git
- 压缩后比原文件大时回落到 store(method=0)
- 打完包要回读验证:逐个 entry inflate → 算 CRC32 → 比对大小 → 与磁盘源文件逐字节比对
给主题加防缓存(避免"改了没效果")
Typecho 核心自己不给静态资源加版本号,所以改 CSS 后浏览器一直用缓存。修法:
// 用文件修改时间做版本号
$ver = @filemtime(__DIR__ . '/../source/css/style.css');
if (!$ver) { $ver = '1.0'; } // 读不到时的兜底
注意: - 所有引用点都要加(主 CSS、暗色切换 JS 里的两个路径、JS 文件),漏一个就白改
- 有些主机 filemtime() 读不到(open_basedir 限制),要多试几个路径并准备后台可手改的兜底版本号
0 评论