尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python+Playwright打造网页变化监控:以figma官图更新为例

Python+Playwright打造网页变化监控:以figma官图更新为例 如果你是因为“figma”三个字点进来的可能会以为这篇又是讲设计工具 Figma 的汉化、MCP 或插件教程。先别急着关掉这里的 figma 是另一个圈子的名字——Max Factory 推出的可动人偶系列标题里“figma 生盐诺亚”“figma 阿妮斯闪耀夏日”指的就是两款即将发售的新品。一个名字两个完全不同的用户群体这件事本身就是典型的“信息歧义”场景。我给这篇文章定一个明确判断无论是追手办官图还是追设计资源更新最原始的做法“每天手动刷新网页”已经不适合现在的信息密度了。与其在几个网站之间来回切换不如用一到两个小时写一个轻量监控程序让它在后台盯着页面内容一变化就自动通知你。这篇文章会以这两条 figma 手办资讯为例带你把整套监控流程跑通环境准备、代码实现、运行验证、常见问题排查最后再补上几条工程化建议。全文面向 CSDN 的技术读者所以重心不在手办本身而在于“信息监控”这个通用开发场景。代码可以复用到非常多地方监控商品页面、监控文档更新、监控依赖版本发布、监控设计稿变更底层思路完全一致。读完你会有一个能直接运行的 Python 脚本也会知道怎么把它挂到定时任务上做到无人值守。1. 为什么“figma”话题最近这么乱以及这篇文章要解决什么问题先把这个歧义说透。在设计师和前端工程师眼里Figma 是当前最流行的在线协作设计工具大家关心的关键词是“figma 汉化”“figma 客户端”“figma MCP”“figma API”。而在手办玩家眼里figma 是可动人偶品牌大家关心的是“什么时候开订”“官图更新了什么”“价格多少”。同一串字母隔着一个屏幕就是完全不同的世界。这种歧义在技术社区里经常制造“搜索无效”你搜“figma”可能同时看到设计软件教程和手办资讯结果哪类都不是你想要的。站在技术写作者的角度看这其实是一个很好的信息过滤案例。搜索词本身没有变但搜索意图差异巨大而搜索平台很难自动判断你到底想要哪一边。这是信息获取成本高的一个典型表现。这篇文章要解决的问题不是帮你在两个 figma 里选一个而是示范“如何用程序监控一个信息源的变化”。我选择手办官图更新作为场景因为它天然具备几个特点页面更新低频但重要错过一次开订可能要等很久信息分散在官网、社交平台、代理商店手动检查枯燥且容易漏。这几个特点和开发者监控依赖版本、监控服务状态几乎没有区别。所以你可以把这篇教程当作一个“页面变更监控器”的实战。后面出现的所有代码都不绑定手办主题你完全可以换个 URL、换组关键词监控任何公开页面。这就是技术方案最有价值的地方具体场景会变通用的监控模型不会变。2. 这次更新的两条 figma 资讯速览先给不熟悉模型圈的读者补个背景。figma 是日本模型厂商 Max Factory 旗下的可动人偶系列特点是关节灵活、配件丰富适合摆出各种姿势。标题里的“figma 生盐诺亚”来自人气游戏作品角色本身是学生制服风格figma 化后通常会还原标志性的发饰、表情和随身道具。“figma 阿妮斯闪耀夏日”则是另一款人气作品中的角色限定造型从名字能看出是夏日主题服装换成了清凉的泳装风格。这类“华丽换装”版本是 figma 系列里比较常见的操作玩家关注的点主要在于涂装质感和配件丰富度。这两条资讯的核心动作都是“官图发售更新”。在模型圈官图发布往往意味着距离开放预订不远了。厂商先公开商品化企划再放出原型白模图再放出彩色涂装官图之后就是公布价格和开订时间。所以看到官图更新的第一反应应该是盯紧后续公告。需要强调一点本文不写具体价格和发售日期因为这类信息变化快且不同地区、不同代理渠道可能不一致。最靠谱的信息来源永远是官方渠道Max Factory 官网、官方社交媒体、授权代理商店页面。我在后面写监控脚本时也会把“优先监控官方页面”作为一条原则。3. 为什么“蹲官图”会成为开发者的痛点先说一个真实场景。你白天写代码晚上想看一眼喜欢的 figma 新品有没有更新官图。打开官网加载半天切到微博看到有人发了张模糊屏摄图不确定真假再切到玩家群群里已经聊了几百条“是不是要开订了”。整个过程至少耗掉二十分钟最后也没找到一张高清官图。这种体验和开发者调试线上问题很像信息分散在日志、监控面板、告警群里如果不去主动盯问题发生了也不一定知道。手办官图更新本质上也是一个“事件通知”问题事件发生时间不可预测但发生后有明确的特征——页面内容变化。更麻烦的是人为盯页面很容易出现“确认偏误”。你因为想要某款产品看到一个类似图片就以为是官图结果转发了错误信息。程序不会这样它只对比内容哈希变就通知没变就不打扰。这种“确定性”是自动化监控的核心价值。还有一个隐藏痛点热度高的 figma 产品开订窗口可能很短尤其是热门角色首批库存可能会在几小时内被抢完。如果只靠手动刷新很难保证第一时间赶上。虽然本文不会帮你抢购但“第一时间知道页面变化”这件事是后续所有操作的前提。所以结论很明确蹲官图不应该靠“每天刷几次”而应该靠“页面变化即通知”。下面开始写代码把这件事变成现实。4. 技术方案选型与核心设计手办官网这类页面很多是前端渲染的直接拿到 HTML 里不一定能读到完整内容。如果只用 Python 的 requests 库请求网页经常拿到一堆 JS 文件路径而不是实际展示的文本和图片。要稳定抓到“人眼看到的内容”需要无头浏览器执行 JavaScript 后再读取 DOM。这里我选择 Playwright。它是由微软维护的浏览器自动化库支持 Chromium、Firefox、WebKit能模拟真实浏览器加载页面等待网络请求完成后抓取内容。相比 SeleniumPlaywright 的 API 更现代自带等待机制对新手更友好。状态存储用 SQLite。理由很直接单文件、免安装、Python 内置 sqlite3 模块直接支持不需要单独起数据库服务。一个监控脚本只需要记住“每个页面最后一次的内容哈希值”SQLite 完全够用。通知模块用 Webhook。企业微信机器人、钉钉机器人、飞书机器人、Server酱等都提供 Webhook 地址脚本只需要向这个地址 POST 一段 JSON。这样既简单又通用本文示例会以企业微信机器人格式为例你换成其他平台时只需要改一下 payload 结构。整体流程分成三步。第一步定时访问目标页面等待页面加载完成后提取 body 文本和所有图片链接第二步把提取到的内容拼在一起计算 SHA256 哈希跟前一次存库的哈希对比第三步哈希不一致就更新数据库并发送通知一致就保持不变。这个设计足够简单也能覆盖大多数“官图新增”的场景。5. 环境准备与前置条件在开始写代码之前先把环境准备好。建议使用 Python 3.9 或更高版本因为 Playwright 对 Python 版本的兼容性较新低版本不一定能安装。如果你的机器上有多个 Python 版本建议用python3 -m venv建一个虚拟环境避免污染全局环境。创建一个项目目录名字随意比如figma-tracker。进入目录后新建一个虚拟环境mkdir figma-tracker cd figma-tracker python3 -m venv venv source venv/bin/activate在 Windows 上激活虚拟环境的命令是venv\Scripts\activate。激活后终端提示符会多出(venv)说明已经进入虚拟环境。接下来安装依赖。我把本次用到的 Python 库放在requirements.txt里方便复现playwright requests python-dotenv然后执行安装命令pip install -r requirements.txt安装完依赖后还需要安装 Playwright 对应的 Chromium 浏览器内核playwright install chromium这个命令会下载一个独立的 Chromium下载体积比较大建议在网络稳定的环境下执行。安装完成后可以运行playwright install --list查看已安装的浏览器。至此环境准备完成。SQLite 不需要单独安装Python 自带sqlite3模块代码里会自动创建数据库文件。下面进入代码实现部分。6. 核心代码实现先给项目搭一个清晰的目录结构。这个项目虽然小但把配置、监控逻辑、通知逻辑分开后面维护会轻松很多figma-tracker/ ├── .env.example # 环境变量模板 ├── requirements.txt # 依赖清单 ├── config.py # 配置读取 ├── monitor.py # 核心监控逻辑 └── notify.py # 通知发送如果你的目标网页不多把配置直接写在config.py里也可以。但我更推荐用.env管理 URL、数据库路径、Webhook 地址因为这样不会把敏感信息提交到 Git。下面先看配置模块。6.1 配置模块 config.pyimport os from dotenv import load_dotenv load_dotenv() # 要监控的页面列表 # 每个元素包含 name、url、keywords 三个字段 # keywords 暂时保留后续可以做内容过滤本期先不启用 TARGETS [ { name: figma 生盐诺亚 官方页面, url: os.getenv(NOAH_PAGE_URL, https://example.com/figma/noah), keywords: [生盐诺亚, figma], }, { name: figma 阿妮斯闪耀夏日 官方页面, url: os.getenv(ANNIS_PAGE_URL, https://example.com/figma/annis), keywords: [阿妮斯, 闪耀夏日], }, ] DB_PATH os.getenv(DB_PATH, state.db) NOTIFY_URL os.getenv(NOTIFY_URL, ) CHECK_INTERVAL int(os.getenv(CHECK_INTERVAL, 300))这里用os.getenv从环境变量里读取配置如果读取不到就使用默认值。你在真实使用时要做的第一件事就是把默认 URL 改成实际要监控的官方页面地址。keywords字段这次先不参与逻辑但留着它有两个好处一是方便你在通知里带上关键词二是后续做内容过滤时可以直接扩展。6.2 通知模块 notify.pyimport requests from config import NOTIFY_URL def send_notification(name: str, url: str) - None: 发送通知到企业微信机器人 Webhook。 if not NOTIFY_URL: print(未配置 NOTIFY_URL跳过通知) return data { msgtype: text, text: { content: f模型情报更新{name}\n链接{url} }, } try: resp requests.post(NOTIFY_URL, jsondata, timeout10) resp.raise_for_status() print(通知发送成功) except Exception as exc: print(f通知发送失败: {exc})这段代码的核心是把“通知”拆成一个独立函数。它做的事情很简单向 Webhook 地址 POST 一段 JSON。如果你用的是钉钉机器人只需要把data改成钉钉要求的格式比如{msgtype: text, text: {content: ...}}其实结构基本一致。这个函数只负责通知任务失败时也不影响主流程继续检查下一个页面。6.3 核心监控逻辑 monitor.pyimport hashlib import json import sqlite3 from playwright.sync_api import sync_playwright from config import TARGETS, DB_PATH, NOTIFY_URL from notify import send_notification def init_db(): conn sqlite3.connect(DB_PATH) conn.execute( CREATE TABLE IF NOT EXISTS page_state ( name TEXT PRIMARY KEY, content_hash TEXT NOT NULL, updated_at TEXT NOT NULL ) ) conn.commit() return conn def load_state(conn, name): row conn.execute( SELECT content_hash FROM page_state WHERE name ?, (name,) ).fetchone() return row[0] if row else None def save_state(conn, name, content_hash): conn.execute( INSERT INTO page_state (name, content_hash, updated_at) VALUES (?, ?, datetime(now)) ON CONFLICT(name) DO UPDATE SET content_hash excluded.content_hash, updated_at excluded.updated_at , (name, content_hash), ) conn.commit() def fetch_page_content(page, url): 访问页面提取 body 文本和所有图片链接合并成字符串。 page.goto(url, timeout30000, wait_untilnetworkidle) text page.inner_text(body) images page.eval_on_selector_all( img, els els.map(el el.src || el.getAttribute(data-src) || ), ) return text ||| json.dumps(images, ensure_asciiFalse) def main(): conn init_db() with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() for target in TARGETS: print(f检查: {target[name]}) try: content fetch_page_content(page, target[url]) content_hash hashlib.sha256(content.encode(utf-8)).hexdigest() old_hash load_state(conn, target[name]) if old_hash is None: print(首次监控记录当前状态不下发通知) save_state(conn, target[name], content_hash) continue if old_hash ! content_hash: print(检测到页面变化更新状态并发送通知) save_state(conn, target[name], content_hash) if NOTIFY_URL: send_notification(target[name], target[url]) else: print(页面没有变化) except Exception as exc: print(f检查 {target[name]} 失败: {exc}) browser.close() conn.close() if __name__ __main__: main()这段代码是整个项目的核心值得逐行拆解。init_db()负责创建 SQLite 数据库和数据表。表结构很简单name是页面唯一标识content_hash是上次抓取的内容哈希updated_at是上次更新时间。如果表已存在CREATE TABLE IF NOT EXISTS不会报错。fetch_page_content()使用 Playwright 的page.goto()访问目标地址wait_untilnetworkidle表示等页面网络请求基本安静后再继续。这样可以尽量避免因为图片或 JS 还没加载完就抓取内容。抓取的内容包括 body 里的所有文字和所有图片链接最后拼成一个长字符串。hashlib.sha256对这个长字符串计算哈希得到的内容摘要可以作为“页面指纹”。为什么用哈希而不是直接比较文本因为哈希固定长度、比较快而且只要内容有任何变化哈希值几乎一定不同。第一次运行时没有旧哈希脚本只记录不通知之后每次运行都会对比新旧哈希一旦不一致就说明页面有更新。通知条件加上if NOTIFY_URL是为了防止 Webhook 没配置时报错。如果暂时不想配通知可以先只打印日志等确认脚本能抓到页面变化后再配置通知。6.4 环境变量模板 .env.exampleNOAH_PAGE_URLhttps://example.com/figma/noah ANNIS_PAGE_URLhttps://example.com/figma/annis DB_PATHstate.db NOTIFY_URLhttps://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyYOUR_KEY CHECK_INTERVAL300使用时复制一份并改名为.env把YOUR_KEY替换成自己企业微信机器人的 key把两个 URL 替换成真实页面地址。注意不要提交.env到 Git建议在.gitignore里加上一行.env。这套代码的扩展点也很清楚。如果你以后想监控多个页面只需要在config.py的TARGETS列表里加一个字典想改成图片更新检测可以把fetch_page_content里的images部分换成单独计算图片列表哈希想加关键词过滤可以使用target[keywords]对文本做一次判断。核心骨架不变。7. 运行与效果验证代码写完后先在命令行里手动运行一次python monitor.py首次运行的预期输出类似下面这样检查: figma 生盐诺亚 官方页面 首次监控记录当前状态不下发通知 检查: figma 阿妮斯闪耀夏日 官方页面 首次监控记录当前状态不下发通知这里有一个关键设计首次运行不通知只记录状态。原因是第一次访问会把页面当前内容存为基线如果这个页面早就更新过了脚本并不知道直接通知会制造噪音。第二次再运行时才开始真正对比。为了验证脚本确实能检测到页面变化你可以先跑第一次记录基线然后修改config.py里的 URL改成另一个内容不同的测试页面再跑第二次。预期输出应该是检测到页面变化更新状态并发送通知如果你没有配置NOTIFY_URL程序会打印“未配置 NOTIFY_URL跳过通知”但依旧更新哈希。这样可以先验证“检测变化”这个核心逻辑再接通知。如果运行失败第一步应该看错误信息是不是来自 Playwright 安装不完整。常见的报错是Executable doesnt exist at ...这说明运行playwright install chromium时没有下载成功。先执行playwright install chromium重试再看其他问题。确认脚本能正常检测页面变化后再把它挂到定时任务。Linux/macOS 使用 crontab例如每 5 分钟检查一次crontab -e在打开的编辑器里添加一行*/5 * * * * cd /path/to/figma-tracker /usr/bin/python3 monitor.py monitor.log 21Windows 用户可以在“任务计划程序”里创建一个任务触发器设为每 5 分钟操作设为运行venv\Scripts\python.exe monitor.py起始目录指向项目目录。定时任务的坑主要在于环境变量和路径。建议在 cron 里使用绝对路径并把日志重定向到文件方便排查。不要写成python monitor.py而不带cd因为 crontab 默认工作目录不是你的项目目录。8. 常见问题与排查思路问题现象可能原因排查方式解决方案Playwright 启动报错提示 Chromium 不存在只安装了 Playwright没有安装浏览器内核运行playwright install chromium重新安装 Chromium 内核页面内容抓取为空页面加载未完成或页面使用反爬机制调整wait_until参数或增加等待时间改用wait_for_selector等待具体元素出现脚本能运行但永远提示“页面没有变化”页面是动态更新但哈希对比的内容没有覆盖关键区域打印抓取内容确认是否包含官图链接扩展提取逻辑把图片链接、视频链接也纳入哈希通知发送失败Webhook 地址错误或网络不通用 curl 手动测试 Webhook检查.env中的NOTIFY_URL中文输出乱码终端编码不是 UTF-8设置PYTHONIOENCODINGutf-8运行前export PYTHONIOENCODINGutf-8定时任务不执行cron 环境变量缺失或 Python 路径错误查看monitor.log使用which python3获取绝对路径cd使用绝对路径这些问题的排查思路对所有 Playwright 脚本都适用。第一个问题最常见因为很多人装完playwright就以为能运行了忽略了浏览器内核也是依赖的一部分。第五个问题在 Windows 上尤其常见建议直接给 Python 设置环境变量。9. 最佳实践与工程建议第一不要用过高频率监控。手办官图不是高频内容每 5 分钟一次已经足够。部分官网有简单的反爬策略如果频繁访问可能触发验证码或封 IP。更合理的策略是每 10 到 30 分钟检查一次甚至一天几次都可以。监控的本质是“不错过”不是“每秒钟都知道”。第二优先监控官方页面不信转载图。网上流传的“官图”很可能只是展会现场实拍或者是玩家自制的渲染图。脚本虽然能告诉你页面变了但无法判断内容是不是真正的官图所以你在收到通知后还是要点击链接确认来源。官方页面是最可信的信息源。第三把敏感信息放进.env不要写死在代码里。Webhook 地址本质上是一个“谁能往群里发消息”的凭证一旦泄露别人就能往你的群里推送垃圾消息。代码写死在 Git 历史里很难清理用环境变量管理要安全得多。第四给脚本加日志。目前代码只是在控制台 print长期跑的话建议写入日志文件。Python 内置的logging模块可以按天滚动方便你回头看上次检测是什么时候、有没有异常。不推荐用print做生产级监控因为服务重启后控制台输出会丢失。第五区分“变化”和“有效变化”。当前方案一有变化就通知但网页里的广告位、侧边栏推荐、访问统计数字都可能变化造成频繁误报。如果你发现通知太多可以改成先抓取图片链接再过滤出包含特定关键词的图片或者只检测某个 CSS 选择器范围内的内容。这样能减少很多无效通知。第六合法合规使用。脚本只能监控你有权访问的公开页面不能绕过登录、验证码不能高频率请求给目标服务器造成压力。在部署到生产环境前最好检查目标网站的 robots.txt 和服务条款。手办资讯监控是个人用途不要把它包装成对外服务去抓取其他平台的内容。第七结合收藏与防骗提醒。官图更新之后开订信息会陆续出现这时候最需要小心骗子。建议只在官方旗舰店、官网、以及熟悉的授权代理渠道下单不要轻信“提前有货”“付定金留名额”的私人转账信息。技术能帮你及时获取信息但最终交易安全还是靠信息核验。10. 总结与后续学习方向这篇文章从“figma”的歧义切入用两条具体的 figma 手办官图更新作为场景完整实现了一个页面变更监控器。核心逻辑不复杂用 Playwright 抓页面内容用 SHA256 计算哈希用 SQLite 记录状态用 Webhook 发送通知。这套代码不止能监控手办资讯稍做修改就能监控任何你关心的页面。对于想继续深入的同学建议按下面几个方向扩展。第一图片级变化检测。现在脚本把文本和图片链接一起算哈希只要图片链接变了就会通知但无法区分“新增了官图”和“图片地址带随机参数”。你可以学习 Pillow 库下载图片后做感知哈希比较两张图的视觉相似度。这对设计稿更新监控尤其有用。第二多站点聚合。把官网、官方社交媒体、代理商店拆成多个 target配置不同的关键词把通知汇总到一个地方。你可以借助消息队列或简单的数据库去重避免同一个消息被多个源重复通知。第三Webhook 之外的通知渠道。企业微信、钉钉、飞书都支持机器人Server酱和 PushPlus 可以直接推送到微信。如果你不想依赖任何 IM也可以写一个简单的邮件发送函数。通知渠道的选择会影响使用体验优先级是可接收、可追溯、可搜索。第四把监控脚本容器化。写一个 Dockerfile安装 Python 和 Chromium然后用 Docker 定时任务或 Kubernetes CronJob 来跑。这样环境依赖、Playwright 浏览器都打进镜像换机器部署非常方便。最后提醒一句监控不是越频繁越好稳定的监控、清晰的通知、可追溯的日志比“每秒钟都在跑”重要得多。希望这篇文章能帮你在信息洪流里省下一点时间把精力留给真正需要人力判断的事。
返回列表