简介:非PDF格式的牛津英语词典翻译数据包,以Excel与SQL两种结构化形式呈现,兼顾语言学习与程序化调用场景。Excel版(words.xls)支持直接编辑、排序与筛选,适合按字母、词性或自定义分类整理词表;SQL版(words.sql)则提供高效检索和结构化存储,可配合Python、Java等语言快速搭建桌面端、Web端或移动翻译工具。压缩包内共2个文件,分别是xls与sql各一个,整体大小仅2.63MB,体量轻、便于分发与导入,目前已有3080人学习下载,适用对象覆盖英语学习者、词典研究者以及有二次开发需求的工程师。拿到后可立即导入Excel或主流数据库,完成单词查询、词表定制,还可作为翻译API的基础数据源,免去手工录词和格式转换的额外成本,整体数据字段清晰、结构紧凑,适合在个人学习和轻量级应用开发中直接复用。
1. 牛津英语词典翻译Excel、SQL版本:不是转格式,是把词典变成能查的数据
你搜『牛津英语词典翻译excel、sql版本(非pdf版本)』,大概率不是想再收藏一份PDF扫描件,而是想把词条翻译做成能筛选、能批量查、能丢进程序里用的结构化词库。PDF只有版面没有结构,你没法对着一页纸做词频统计,没法把释义批量灌进背单词软件,也没法在Excel里查一个词条顺手把音标捞出来。Excel版能筛能排,SQL版能查能联表,这两者才是词典数据该有的形态。我按三件事拆开讲:字段怎么定、SQL和Excel分别怎么做、以及从PDF或网页转数据时最容易踩的那几个坑。
2. 先定字段再动手:牛津词条拆表前的结构设计与数据来源
2.1 一条牛津词条里有哪几件“零件”
不管你是从网页抓、从API拿、还是对着已有词库人工整理,最后都要落到同一个结构上。一条词条至少包含:词头headword、英式音标、美式音标、词性、义项、英文释义、中文翻译、例句、例句翻译。牛津这类学习型词典的释义和例句都是精心写过的,中文翻译往往不是逐词直译,而是按义项人工对应,所以“一个词条一行”这种偷懒做法在这里撑不住。
多义词是第一个要面对的现实。像“set”“run”“light”这类词,牛津词典里会有十几个甚至几十个义项,每个义项有自己的词性、释义、翻译和例句。如果全部拼在一个单元格里,筛选“名词词性”时完全使不上劲。我一般会把词条拆成“词头层、义项层、例句层”三层来设计字段,这也是后面SQL表和Excel表共同的骨架。
音标字段我建议拆两列:phonetic_uk、phonetic_us。见过有人把两个音标拼成一列,写成一串像“/ˈæbəndən/; /əˈbændən/”的样子,看起来省事,后面想做“哪些词没有英式音标”这类筛选就完全没法查。宁可多一列,也别把两个信息塞同一格。
2.2 常见的数据来源有三种,PDF为什么不在其中
第一种是抓在线词典页面。一般用requests抓词条详情页,再用BeautifulSoup或lxml按页面结构抽取词头、音标、义项列表和例句块,抓下来的是HTML片段,清洗后写成结构化记录。这种方式的优点是释义和例句都是“人编辑过的”,质量上限最高;缺点是排重、断行、义项编号识别都得自己写规则。第二种是用已有的学习型词库做底子,把词头、翻译拿过来,再对照牛津释义人工校准高频词。优点是上手快,缺点是低质量来源的错译会悄悄混进来。第三种是官方提供的API或订阅数据包,返回JSON或XML,字段现成,这是做产品最省心的路,但个人拿来练手往往成本偏高,这里不展开讲。
PDF的位置很尴尬。PDF是排版产物,段落、双栏、连字符断词、OCR识别错误这些都会在“转数据”时变成额外负担。即使你成功把PDF转成了文本,仍然要按词条边界重新对齐,这个工程量比直接抓网页大得多。所以标题特意强调“非pdf版本”,不是PDF不好,而是它作为数据源会让后续每一步都付出代价。
2.3 最小字段集与三张表拆分
下面是落地时最少需要的字段,每个字段一行,对应清洗后的原始数据,不含任何派生字段:
| 层级 | 字段 | 说明 |
|---|---|---|
| 词头层 | word_id | 词条唯一ID,整数 |
| 词头层 | headword | 词头,如 abandon |
| 词头层 | phonetic_uk | 英式音标 |
| 词头层 | phonetic_us | 美式音标 |
| 义项层 | sense_order | 义项序号,保留词典原始顺序 |
| 义项层 | pos | 词性,如 v./n./adj. |
| 义项层 | definition_en | 英文释义 |
| 义项层 | translation_zh | 中文翻译 |
| 例句层 | example_en | 英文例句 |
| 例句层 | example_zh | 例句中文翻译 |
有了这个字段集,表结构就很自然了:words表放词头层,senses表放义项层,examples表放例句层。这里要说明一个常见误区:examples和senses不是简单的一对多关系,一个义项下往往有两条以上例句,所以例句不能塞进senses表。而一个词头对应多个义项,如果音标放senses表,同一条词的音标会被重复存十几遍,数据量一大就会白白膨胀。用word_id和sense_id做外键串联,才是词典数据该有的标准形态。这个设计定好之后,后面建表、导入、导出Excel都不用返工。
3. SQL版本落地:建表、批量导入和一条能直接用的查词SQL
3.1 用SQLite建三张表:主键、外键和索引一次写对
SQL版本我首选SQLite,原因很实在:单文件、免安装、Python自带驱动,交付给谁都能跑。标题里说的“SQL版本”,落到最小可行方案就是一份dictionary.db。下面是三张表的建表语句。
CREATE TABLE words ( word_id INTEGER PRIMARY KEY AUTOINCREMENT, headword TEXT NOT NULL UNIQUE, phonetic_uk TEXT, phonetic_us TEXT, level TEXT ); CREATE TABLE senses ( sense_id INTEGER PRIMARY KEY AUTOINCREMENT, word_id INTEGER NOT NULL REFERENCES words(word_id), sense_order INTEGER NOT NULL, pos TEXT, definition_en TEXT, translation_zh TEXT ); CREATE TABLE examples ( example_id INTEGER PRIMARY KEY AUTOINCREMENT, sense_id INTEGER NOT NULL REFERENCES senses(sense_id), example_en TEXT, example_zh TEXT ); CREATE INDEX idx_senses_word ON senses(word_id); CREATE INDEX idx_examples_sense ON examples(sense_id);逻辑说明:words表把headword设为UNIQUE,防止同一词头被重复导入;senses表里word_id指向words,sense_order保留牛津义项顺序,这个顺序丢了,释义的先后层级也就丢了;examples表挂在sense_id上,一个义项多条例句都能往里放。
参数上要注意两处:一是主键用INTEGER PRIMARY KEY可以得到自增ID,不用额外写AUTOINCREMENT也可以;二是索引只建在外键列上,查询时JOIN走索引,十几万条词条的查询也能在毫秒级返回。level字段如果暂时没有来源,可以留空,后面做词频分级时再填充。
3.2 用Python参数化导入:别自己拼INSERT语句
从网页抓下来或从现有文件清洗出来的数据,通常先落成CSV,再进数据库。这里我坚持用Python的executemany参数化,而不是把值直接拼进SQL字符串里。原因后面避坑章会细说,先看代码。
import sqlite3 import csv conn = sqlite3.connect("dictionary.db") cur = conn.cursor() with open("senses.csv", encoding="utf-8") as f: reader = csv.DictReader(f) rows = [] for r in reader: rows.append(( int(r["word_id"]), int(r["sense_order"]), r["pos"], r["definition_en"], r["translation_zh"] )) cur.executemany( "INSERT INTO senses (word_id, sense_order, pos, definition_en, translation_zh) " "VALUES (?, ?, ?, ?, ?)", rows ) conn.commit() conn.close()这段代码的要点:DictReader按表头取列,CSV列名必须和字段对应;values用五个问号占位,真正写入时由SQLite驱动处理转义,释义里的单引号、双引号、换行符都不会破坏语句;executemany一次性批量执行,比循环execute快一个数量级。words.csv、examples.csv走同一套逻辑,换掉表名和字段就能用。
注意:CSV里如果有字段内换行,导入前最好统一替换成空格,否则数据库端和Excel端都会出现“莫名其妙的断行”。
3.3 兜底方案:SQLite命令行直接倒CSV
如果手上没有Python环境,SQLite自带的命令行工具也能完成导入,前提是表已经按3.1建好。
sqlite3 dictionary.db .headers on .mode csv .import --skip 1 words.csv words .import --skip 1 senses.csv senses说明:进入sqlite3交互界面后,先设.mode csv,这样带引号的字段会被正确解析;--skip 1表示跳过CSV第一行表头,如果文件本身没有表头就去掉这个参数。这个方案的痛点是CSV里一旦有字段内换行,.import会把一行数据拆散成两行,导入后行数对不上很难发现。所以它只适合数据已经足够干净的场景,正经做法还是Python那套。
3.4 把“查词”变成一条SQL:导入工作有没有白干,看这个查询
表建好、数据导完,第一件事不是去看总量,而是查一个真实单词验证整条链路。我用“abandon”这种多义词测试,它既有动词义项又有名词义项,能同时检验关联和排序。
SELECT w.headword, w.phonetic_uk, w.phonetic_us, s.sense_order, s.pos, s.translation_zh, s.definition_en, e.example_en, e.example_zh FROM words w JOIN senses s ON s.word_id = w.word_id LEFT JOIN examples e ON e.sense_id = s.sense_id WHERE w.headword = 'abandon' ORDER BY s.sense_order, e.example_id;这里用LEFT JOIN而不是INNER JOIN,是为了让“没有例句的义项”也出现在结果里,而不是被丢掉。查到结果后先核对两件事:义项条数和词典原页面是否一致,音标字段是否填到了正确的列里。如果返回的记录里出现重复的义项,多半是examples表里例句没做好分组,回头检查清洗脚本即可。如果一条都查不出来,先单独确认词头是否在words表里:SELECT word_id FROM words WHERE headword = 'abandon'; 如果words有而senses没有,问题出在senses的word_id映射错位,通常是来源文件里ID列被Excel转成了科学计数法。
如果后续要迁移到MySQL或PostgreSQL,改动不大:SQLite的AUTOINCREMENT换成MySQL的AUTO_INCREMENT;TEXT字段在PostgreSQL里改为TEXT或VARCHAR即可。这里三张表不涉及时间字段,迁移基本是复制粘贴级别的工作。
4. Excel版本落地:从SQL导出到一份能日常筛选的工作簿
4.1 用pandas把三张表导成多Sheet工作簿
SQL库是给程序用的,Excel是给人用的。把dictionary.db导出成xlsx,我一般用pandas一步到位,让它生成三个Sheet:词表、义项表、例句表。
import sqlite3 import pandas as pd conn = sqlite3.connect("dictionary.db") words = pd.read_sql_query( "SELECT word_id, headword, phonetic_uk, phonetic_us, level FROM words", conn ) senses = pd.read_sql_query( "SELECT sense_id, word_id, sense_order, pos, definition_en, translation_zh FROM senses", conn ) examples = pd.read_sql_query( "SELECT example_id, sense_id, example_en, example_zh FROM examples", conn ) with pd.ExcelWriter("oxford_export.xlsx", engine="openpyxl") as writer: words.to_excel(writer, sheet_name="词表", index=False) senses.to_excel(writer, sheet_name="义项表", index=False) examples.to_excel(writer, sheet_name="例句表", index=False)说明:engine指定openpyxl,这是pandas写xlsx的默认写入引擎,显式写出来能避免环境里同时装了多个写入引擎时行为不一致;sheet_name用中文,常见表格软件都能正常显示;index=False必须加,否则会把pandas的默认行号写进第一列,混进数据里很碍事。
导出后再检查一个细节:工作簿里每个sheet的列宽。pandas导出的列宽是统一默认值,音标列、例句列显示出来很挤。我一般导出后手动选中全列,统一调整到合适宽度,一次调整只影响展示,不会改数据。
4.2 多义词拆行导出:一个义项一行,而不是一个词条一行
这是Excel版本最重要的一步。有人喜欢把某个词的多个义项用顿号拼进一个单元格,看起来跟词典排版相似,但这张表一到筛选场景就废了。
merged = senses.merge( words[["word_id", "headword", "phonetic_uk", "phonetic_us"]], on="word_id", how="left" ) cols = [ "headword", "phonetic_uk", "phonetic_us", "sense_order", "pos", "translation_zh", "definition_en" ] merged[cols].sort_values( ["headword", "sense_order"] ).to_excel("查词总表.xlsx", index=False)这段代码把词表和义项表按word_id合并,然后以义项为单位输出。headword、音标这些词头层字段在每行都会出现,但这正是Excel筛选所需要的;词性、中文翻译、英文释义每行一个义项的值。生成后的“查词总表”里,每个单词占N行,N等于义项数。筛选“pos = v.”能直接得到动词义项清单,筛选“translation_zh为空”能找出还没补翻译的词条,这都是一词条一行做不到的。
例句我没有合进这张总表,原因很现实:一个义项多条例句会让同一行反复重复,表格膨胀到几万行且视觉混乱。例句单独留在“例句表”Sheet,配合义项表里的sense_id取用即可。
4.3 三件套:冻结首行、下拉筛选、空值标红
文件生成后,进到表格软件里做三件事,加起来三分钟:
一是冻结首行。选中A2单元格,视图→冻结窗格→冻结首行。这样往下滚动时表头一直可见,查词不会看到一半不知道哪列是什么。
二是启用筛选。选中表头行,按Ctrl+Shift+L,表头单元格会出现下拉箭头。词性筛选、音标是否为空筛选、按释义关键字筛选都能在这一步完成。
三是标红空值。选中translation_zh整列,开始→条件格式→新建规则,选“只为包含以下内容的单元格设置格式”,下拉选“空”,设个浅红填充。这样哪些词条还没翻译,一眼就能扫出来。
这三件套做完,这份Excel才算是“能日常用的版本”。如果还要发给别人用,再补一层:把第一个Sheet命名为“使用说明”,写两行字说明每个Sheet是什么、多义词为什么占多行。
4.4 VLOOKUP在词库上的边界:INDEX/MATCH组合更稳
拿到词库后,很多人第一个想法是VLOOKUP查词,但它有三个限制:查找值必须在所选区域第一列;返回列只能往右取;多义词只会返回第一个匹配项。查“abandon”问题不大,查“set”这种几十个义项的词,VLOOKUP只能返回第一个义项,极易误导。
=VLOOKUP(A2, 义项表!$A:$G, 6, FALSE) =INDEX(义项表!$F:$F, MATCH(A2, 义项表!$A:$A, 0))两个公式都返回F列的中文翻译。VLOOKUP要求查找值A2必须在义项表第一列,这是它的硬限制;INDEX/MATCH的查找列可以随意指定,哪怕词头不在第一列也能工作。MATCH的第三个参数0表示精确匹配,查词典绝对不能省略这个参数,省略掉默认是近似匹配,查“abandon”可能给你返回“abandoned”。真要按义项序号取第2个、第3个义项,配合SMALL和IF数组公式也能做,但日常使用里用筛选反而更实际。
5. 常见问题排查:PDF转Excel/SQL时最容易翻车的5类状况
5.1 CSV导入表格软件中文乱码
现象:把清洗好的CSV直接双击打开,英文正常,中文字段全部变成“鍙h”这类的乱码。
原因:文件是UTF-8编码,而部分表格软件默认按ANSI(GBK)解析无BOM的UTF-8文件。
解决:写CSV时使用utf-8-sig编码,也就是带BOM的UTF-8。Python里一行改动:open("senses.csv", "w", encoding="utf-8-sig", newline="")。如果文件已经生成,用软件的“数据→自文本/CSV”导入,导入时手动选择文件原始编码为UTF-8,同样能救回来。
5.2 释义里的单引号把SQL语句打断
现象:用字符串拼接INSERT语句,导到“don't”“it's”这类词时直接报错syntax error,或者数据只插入了一部分,库里出现半截英文。
原因:直接在SQL里写值,英文释义中的单引号提前结束了字符串,双引号、反斜杠同理。最常见的写法是“INSERT INTO senses VALUES ('" + text + "')”,这种写法在词典数据面前必炸。
解决:改用3.2的参数化写法,由驱动做转义;或者先在Python里把文本里的引号统一替换成全角引号,但这样数据被改脏了,不推荐。已经导入的库可以用SELECT语句查释义带单引号的词条,确认它们是否被正确存储。
5.3 音标字段在Excel里显示成方框“□”
现象:导入表格软件后音标列全是方块,复制到文档里又正常。
原因:该字符是国际音标IPA符号,当前单元格字体缺少对应字形。
解决:选中音标列,字体改成“Gentium”“Doulos SIL”或“Arial Unicode MS”,这些字体覆盖IPA字符集。如果整个工作簿要发给别人,最好在“使用说明”Sheet里写一句“音标列请用Arial Unicode MS字体查看”,避免别人打开看到一片方框又来找你。
5.4 PDF转出来的例句断行、OCR错字污染整个词条
现象:例句末尾多出半个单词,或者出现“aband0n”这种字母被替换的错词,整条释义在表格里断成两行。
原因:PDF转文本时保留了版面的软换行,OCR对低质量扫描件会把字母识别错,双栏版式还会让左右两栏内容混在一起。这不是清洗脚本的问题,是数据源本身就不适合做结构化提取。
解决:如果只有PDF这一个来源,转文本后必须按词头重新对齐所有段落,再把明显错误的OCR词(含数字替换字母、乱码)抽出来人工核对。稳妥做法是放弃PDF,直接抓在线词条页,网页里的结构标签比PDF版面好处理一个数量级。这个坑是“非pdf版本”存在的根本原因。
5.5 word_id变成科学计数法,例句尾部神秘消失
现象:Excel里word_id列显示成1.23457E+10,点进去编辑栏看到的数字和原始ID对不上;例句列末尾几个字符丢失。
原因:Excel默认常规格式遇到超过12位的数字自动转科学计数法,显示精度有限;xlsx单单元格也设了字符串长度上限,部分工具在写超长字符串时会截断。
解决:ID字段尽量不设计成超长整数,用自增整形或文本型都可以;导入表格软件前把目标列设置为“文本”格式。检查例句是否被截断,可以导出后用LEN函数扫一遍长度分布,出现整整齐齐的长度突然下降,基本上就是被截断了。
6. 进阶验证:三条SQL给词库做体检,再用SQLite做一个免安装本地查词工具
6.1 用SQL做数据体检
交付词库之前,我会用一组SQL把数据质量快速过一遍。总词数对得上来源词表,音标空值比例在预期内,例句覆盖没有明显塌方,这几点确认了再发出去。
SELECT COUNT(*) AS total_words FROM words; SELECT COUNT(*) AS words_without_phonetic FROM words WHERE phonetic_uk IS NULL AND phonetic_us IS NULL; SELECT COUNT(*) AS senses_without_example FROM senses s LEFT JOIN examples e ON e.sense_id = s.sense_id WHERE e.example_id IS NULL; SELECT headword, sense_order, pos FROM senses WHERE translation_zh IS NULL OR trim(translation_zh) = '' ORDER BY word_id LIMIT 20;四条查询分别回答四个问题:总词量多少、多少词头完全没音标、多少义项没有例句、哪些义项缺中文翻译。体检不是一次性的,每轮更新数据后都跑一遍,能让翻车发生在自己端而不是交付之后。
6.2 增量更新词库:整词条覆盖比逐条UPDATE省心
词库更新时,逐条UPDATE看起来很精准,但多义词的义项数会变,旧义项会残留成脏数据。我一般做整词条覆盖:words表用INSERT OR REPLACE按headword更新;senses表先执行DELETE FROM senses WHERE word_id = ?,再把新义项重新插入;examples表同理。这样一轮更新后库里不会留下任何旧义项,排序、词性、例句全按新版词典重来。
6.3 把SQLite文件直接交付,Excel也能反向查询
做完的dictionary.db只是一个单文件,不需要装数据库服务,接收方用Python或任意SQLite客户端就能查。部分新版本表格软件也支持连接SQLite文件,把词库当外部数据源反向使用,生成自己的透视表。做手机端工具时,把dictionary.db放进应用资源目录,本地查词不需要联网。这套从Excel到SQLite再到移动端的链路,核心就是三张表和前面那些导入导出脚本,方向一旦反了,后面每一步都在补救。我现在做任何词典类数据,都坚持先SQLite三表再按场景导Excel,这顺序救过我很多次。希望帮到你。
本文还有配套的精品资源,点击获取