Source-led reverse engineering

Cambridge Dictionary 词典后台数据结构推断

以 English–Chinese (Simplified) / sense 页面源码为样本,将可观察的 HTML 数据锚点还原为一个可落地的词典领域模型。

抓取地址:dictionary.cambridge.org/dictionary/english-chinese-simplified/sense?q=Sense分析口径:页面结构,不声称官方内部实现

先看结论

页面不是“一个单词一行”的平面数据,而是 词头(headword)→ 词性条目(entry)→ 义项(sense)→ 翻译、例句、短语、发音 的聚合结果。最可靠的主键线索是义项上的 data-wl-senseid,例如 ID_00028824_01。

源码事实结构推断实现建议
2词性条目:noun / verb
12稳定义项 ID
57例句节点(含折叠例句)
14固定短语块
12英美音频 source 组

推断的聚合关系

实线边界表示页面中直接出现的层级;橙色节点是建议的持久化实体,名称是对源码语义的归一化。

HEADWORD词头 Wordsense、规范拼写、URL slug、语言方向
ENTRY词性条目 Entrynoun / verb;每个条目有独立发音、语法标签
SENSE义项 Sense定义、等级 B1/B2/C2、可数性 C/U、sense_id
TRANSLATION翻译 Translation一个义项可有多个中文目标词,顺序与标点应保留
EXAMPLE例句 Example英文句、对应中文句、义项外键、语法框架
PHRASE短语 Phrase如 sense of fun;有独立义项和短语标签
PRONUNCIATION发音 PronunciationUK/US、IPA、MP3/OGG 资源地址
LABEL标签与代码CEFR、语法、地区、guide word、用法说明

建议的关系模型

-- 这是推断模型,不是 Cambridge 官方 DDL word (id, lemma, slug, source_lang, target_lang) 1 ─── N entry (id, word_id, part_of_speech) 1 ─── N sense (sense_id, entry_id, guide_word, definition_en, level, grammar_code, sort_order) 1 ─── N translation (sense_id, text_zh, ordinal) 1 ─── N example (sense_id, text_en, text_zh, grammar_code, ordinal) 1 ─── N phrase (entry_id, phrase_text, region) 1 ─── N sense 1 ─── N pronunciation (entry_id, region, ipa) 1 ─── N audio_asset (pronunciation_id, format, uri)

为什么要拆 Word 与 Entry?

同一拼写同时作为名词和动词出现,源码中有两个 entry-body__el 与两个发音头部。若只保留一个 word 记录,会丢失词性边界。

为什么 Sense 必须独立?

一个词性下有多个 def-block,每块都有独立的 data-wl-senseid、定义、译文和例句集合;这正是学习收藏、词义统计和内容更新的稳定粒度。

为什么翻译不是一个字符串?

源码把同一义项的中文译词拆成多个 .dtrans,中间用分号或顿号表达顺序。建模为多行才能保留检索和展示语义。

源码证据与字段映射

证据锚点页面表现字段/实体含义判断
entry-body__el出现 2 次;头部词性分别为 noun、verbentry.part_of_speech,归属于同一 word事实
data-wl-senseidID_00028824_01 到 _12sense.sense_id;适合作为外部内容锚点事实
def-info / epp-xrefB1、B2、C2 等等级标签sense.level,建议字典表约束事实
gram dgram / gc dgcC、U、T、+ (that)、+ question wordgrammar_code 或 grammar_feature 多值关系事实
dtrans + lang=zh-Hans义项译文、例句译文均有独立节点translation 可区分 meaning/example 两种用途事实
examp dexamp / eg deg英文例句;部分带中文对应句和语法框架example.text_en/text_zh,按 sense 关联事实
phrase-block / phrase-titlesense of fun、in a sense 等phrase 是 entry 下的复合词组容器事实
dpron-i / ipa / audio sourceUK/US、IPA /sens/、MP3 与 OGGpronunciation + audio_asset事实
页面的重复嵌套边界译文、例句、短语都嵌套在某个 def-block 或 entry 下外键应落在 sense_id / entry_id,而不是通过文本匹配推断
URL 与词头组合/english-chinese-simplified/sense建议 word.slug 唯一,但保留来源和版本字段推断
跨词链接 .query定义和例句中的词链接回词典 URL可增加 lexical_link,不要把链接文本硬编码为正文推断

字段字典:从页面到存储

word.lemma

VARCHAR / normalized

当前值为 sense。用于搜索和去重;不要把大小写查询词 Sense 当作另一词头。

entry.part_of_speech

ENUM 或 dictionary_id

页面直接给出 noun / verb。建议受控字典,避免自由文本漂移。

sense.sense_id

VARCHAR(32) UNIQUE

源码里的 ID_00028824_01。可作为导入幂等键,但仍需内部数值主键。

sense.definition_en

TEXT + markup

定义含可点击词条、粗体语法提示和 gloss。建议存规范文本及安全渲染片段。

translation.text_zh

TEXT + ordinal

一个 sense 可拆出多个目标词;保留顺序、语言 zh-Hans 与用途。

example.text_en / text_zh

TEXT / nullable

中文例句并非每个英文例句都有,必须允许空值并保留展示顺序。

pronunciation.region / ipa

UK|US / VARCHAR

发音属于 entry 而非单个 sense;当前两种地区都为 /sens/。

audio_asset.uri

URI + format

MP3、OGG 是同一发音资产的不同编码;不建议把扩展名解析逻辑放在业务层。

content_version

BIGINT / timestamp

页面未显式暴露版本号,但生产系统应加入,用于缓存失效、重抓和差异同步。

需要保留的不确定性

这不是官方数据库逆向结果

HTML 只能证明渲染契约和数据粒度,不能证明 Cambridge 后台使用 SQL、文档库还是搜索索引。上面的实体/外键是兼容页面结构的推荐模型。

义项 ID 是否全站永久稳定?

当前页面把它用于“加入词汇表”,因此至少在该功能作用域内需要稳定。跨版本永久性仍应通过抓取多日期页面或接口响应验证。

定义里的 HTML 应该如何存?

页面定义含链接和强调标记。建议同时保存 clean_text、受控 rich_text,以及从链接中抽出的 lexical_link,避免把原始 HTML 直接当可信模板。

多语言页面如何扩展?

把 dictionary edition(如 english-chinese-simplified)作为 edition/locale 维度;translation、example_translation 和 UI 文案都挂到语言代码,不要为每种语言复制整套表。

高词头、词性、义项、例句、短语、发音的页面层级
中实体拆分、主外键和排序字段
低真实存储引擎、内部表名、缓存与搜索实现