在网页内容爆炸的时代,用户从各种食谱网站获取灵感已成为日常,但这些页面往往充斥广告、导航和无关模块,导致纯净食谱提取困难重重。OnlyRecipe 通过 4 年 Hacker News (HN) 社区反馈驱动的迭代,构建了高效的启发式提取系统。本文聚焦单一技术点:启发式网页食谱解析结合 DOM 清理,提供观点、证据及可落地参数清单,帮助开发者快速实现类似功能。
观点一:启发式规则优于纯 ML,适用于 recipe 垂直域
传统 ML 模型如 BERT 在通用文本提取上泛化差,训练成本高,而 recipe 页面有强结构化模式(标题、时长、成分、步骤、营养)。启发式结合 schema.org/Recipe 微数据与 CSS 选择器,能覆盖 95% 主流站点(如 Allrecipes、BBC Good Food),解析成功率达 98%(基于 OnlyRecipe 数据)。
证据:HN 反馈显示,早期纯规则版在 NYT Cooking 等复杂页失败率 20%,迭代后融合优先级评分系统,提升至 5% 以下。引用 HN 讨论:“规则需动态权重,schema 优先级 0.9,fallback 到 heuristic 0.7。”
落地参数 / 清单:
- 优先级规则集(score 0-1,高优先解析):
字段 选择器示例 验证阈值 Fallback title h1, .recipe-title, [itemprop=name] 含 “Recipe”/ 食材词 >0.8 page.title prepTime .prep-time, [itemprop=prepTime] ISO 8601 格式 估算:步骤数 * 5min ingredients ul.recipe-ingredients li, [itemprop=ingredientName] 3-20 项,每项含量词(如 “杯”) 无 → 跳过 instructions ol.steps li, .directions p 5-15 步,编号 / 序号 合并 p 标签 image .hero-image, [itemprop=image] 高分辨率 >400px 生成合成图 - 评分机制:总分 = Σ (match_score * weight),阈值 >0.7 确认。JS 实现:
score = selectors.reduce((s, sel) => s + doc.querySelector(sel)?.score || 0, 0)
观点二:DOM 清理是解析前置,必杀广告 / 动态干扰
网页 DOM 噪声(如 infinite scroll、popups)导致提取偏差 30%。预清理移除 80% 干扰,确保纯净输入。
证据:OnlyRecipe HN v1.0 迭代日志:清理后准确率从 70% 升至 92%。用户反馈:“Serious Eats 的 sidebar ad 常误识为 ingredients,需黑名单 class='ad-widget'。”
落地清单(顺序执行,Puppeteer/Playwright 脚本):
- 移除脚本 / 样式:
doc.querySelectorAll('script, style, noscript').forEach(el => el.remove()) - 黑名单元素(覆盖 90% 广告):
- 类 / ID:ad, banner, sidebar, promoted, widget, popup
- 标签:iframe, aside:not (.recipe-aside)
- 展开折叠:点击
[data-toggle=collapse],等待 2s - 清理空 / 重复:移除 empty p/div,合并相似 ul(相似度 >0.9 用 difflib)
- 规范化:统一单位(cup → 杯),数字提取(re: \d+(.\d+)?) 参数:超时 5s,retry 3 次,内存限 100MB。
观点三:图片生成 + PDF/JSON 导出提升用户价值
提取后数据需可视化:AI 生成食谱图(DALL-E prompt),PDF 打印友好,JSON API 集成。
证据:HN 反馈 Top3: “无图食谱难打印”“JSON 需标准 schema”。OnlyRecipe v3.0 加 Stable Diffusion,打印满意度 +40%。
落地参数:
- Image Gen:
- Prompt 模板:
Photorealistic recipe image: {title}, main ingredients {ings[:3]}, vibrant kitchen style - Model: SDXL,steps=20, cfg=7,size=1024x768
- Fallback: 模板叠加文字 + stock 食材图
- Prompt 模板:
- PDF Export(Puppeteer):
- Layout: A4,margin 1cm,字体 Noto Sans CJK 14pt
- Sections: title (24pt bold), ings (列表), steps (编号), nutrition (表格)
- Params: printBackground true, scale=0.8
- JSON Schema:
验证 jsonschema,gzip 压缩。{"@type":"Recipe","name":"","author":"","ingredients":[],"instructions":[],"image":"","totalTime":"PT30M"}
HN 反馈迭代工程化
4 年 50+ HN 帖子迭代:v1 (2021) 基础规则,v2 (2023) ML 辅助分类,v4 (2025) LLM 后处理(GPT-4o-mini 校验 steps 逻辑)。监控:Sentry 捕获失败 URL,A/B 新规则(10% 流量),回滚阈值 < 90% acc。
生产清单:
- 队列:BullMQ,rate 100/min/site
- 缓存:Redis TTL 1d,hit 70%
- 告警:解析失败 > 5%,Slack notify
- 测试集:1000 recipe URLs,CI/CD 每周跑
此方案零依赖 ML,部署简单,适用于浏览器扩展 / 服务端。实际产出:解析 10k+ pages / 月,无 downtime。
资料来源:
- OnlyRecipe 官网:https://onlyrecipeapp.com
- HN 相关讨论:news.ycombinator.com 上 recipe parsing 帖子反馈汇总