当前位置: 首页 > news >正文

剑桥词典API实战:用Python爬取单词释义、发音和例句(附完整代码)

剑桥词典数据自动化采集实战:Python逆向工程与语音库构建指南

在语言学习工具开发领域,剑桥词典因其权威释义和标准发音成为众多开发者的首选数据源。本文将揭示如何通过Python技术栈实现词典数据的自动化采集,包括释义解析、发音文件下载以及例句提取,为开发者构建个性化语言学习工具提供完整技术方案。

1. 环境准备与目标分析

构建自动化采集系统前,需要明确技术路线和工具链。不同于官方API调用,我们采用网页解析与文件规律分析相结合的方式实现数据获取。

基础环境配置:

# 核心依赖库 import requests from bs4 import BeautifulSoup import re import json from urllib.parse import quote import os # 语音下载专用库 import wget from pydub import AudioSegment

剑桥词典网页结构特点分析:

  • 单词查询URL格式固定:https://dictionary.cambridge.org/dictionary/english/{word}
  • 发音文件存储路径遵循特定命名规则
  • 词性分类使用特定CSS类标识
  • 例句存在于结构化HTML标签中

提示:实际操作前建议配置合理的请求间隔(如3-5秒),避免触发反爬机制

2. 网页结构逆向工程

2.1 基础请求与反爬策略

实现稳健的数据采集需要处理网络请求的各种异常情况:

def safe_request(url, max_retry=3): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept-Language': 'en-US,en;q=0.9' } for attempt in range(max_retry): try: resp = requests.get(url, headers=headers, timeout=10) if resp.status_code == 200: return resp elif resp.status_code == 429: time.sleep(10) # 请求过频处理 continue except Exception as e: print(f"Attempt {attempt+1} failed: {str(e)}") time.sleep(5) return None

2.2 关键数据定位技术

通过分析DOM结构,我们发现主要数据分布在特定标签中:

def parse_word_page(html): soup = BeautifulSoup(html, 'html.parser') # 词性区块定位 pos_blocks = soup.find_all('div', class_='pr entry-body__el') data = { 'word': soup.find('span', class_='hw dhw').text, 'pronunciation': {}, 'definitions': [], 'examples': [] } # 发音文件提取逻辑 uk_audio = soup.find('source', {'type': 'audio/mpeg', 'src': re.compile('uk_pron')}) us_audio = soup.find('source', {'type': 'audio/mpeg', 'src': re.compile('us_pron')}) if uk_audio: data['pronunciation']['uk'] = uk_audio['src'] if us_audio: data['pronunciation']['us'] = us_audio['src'] # 释义提取逻辑 for block in pos_blocks: pos = block.find('span', class_='pos dpos').text def_blocks = block.find_all('div', class_='def-block ddef_block') for def_block in def_blocks: definition = def_block.find('div', class_='def ddef_d db').text example = def_block.find('span', class_='eg deg') data['definitions'].append({ 'pos': pos, 'definition': definition, 'example': example.text if example else None }) return data

3. 发音文件系统化采集

3.1 发音文件URL规律解析

通过分析数百个单词的发音文件路径,我们发现以下命名模式:

组件示例生成规则
首字母目录u单词首字母
二级目录ukn单词前2-3字母
三级目录uknot单词前4-5字母
文件名uknotif012单词+数字后缀

实现代码:

def build_pronunciation_url(word, accent='uk'): """根据单词生成可能的发音文件路径""" first_char = word[0].lower() two_chars = word[:2].lower() if len(word) > 1 else first_char three_chars = word[:3].lower() if len(word) > 2 else two_chars base_url = f"https://dictionary.cambridge.org/media/english/" path = f"{accent}_pron/{first_char}/{two_chars}/{three_chars}/" # 尝试常见数字后缀 for i in range(1, 10): filename = f"{three_chars}{i:02d}.mp3" full_url = base_url + path + filename if requests.head(full_url).status_code == 200: return full_url return None

3.2 语音文件处理技巧

获取音频文件后,通常需要进行格式转换和标准化处理:

def process_audio(filepath): """统一音频格式和质量""" audio = AudioSegment.from_file(filepath) # 标准化处理 audio = audio.set_frame_rate(22050) audio = audio.set_channels(1) audio = audio.normalize() # 保存为标准格式 output_path = filepath.replace('.mp3', '_processed.wav') audio.export(output_path, format='wav', bitrate='16k') return output_path

4. 数据存储与应用集成

4.1 结构化存储方案

采集的数据建议采用混合存储策略:

def save_word_data(word_data, storage_dir): """保存单词数据到文件系统""" word = word_data['word'] # 创建单词目录 word_dir = os.path.join(storage_dir, word.lower()) os.makedirs(word_dir, exist_ok=True) # 保存JSON元数据 with open(os.path.join(word_dir, 'meta.json'), 'w') as f: json.dump({ 'definitions': word_data['definitions'], 'examples': word_data['examples'] }, f, indent=2) # 下载发音文件 for accent, url in word_data['pronunciation'].items(): filename = f"{word}_{accent}.mp3" wget.download(url, os.path.join(word_dir, filename)) return word_dir

4.2 数据库集成示例

对于大规模应用,建议使用MongoDB存储结构化数据:

from pymongo import MongoClient class DictionaryDB: def __init__(self, uri='mongodb://localhost:27017/'): self.client = MongoClient(uri) self.db = self.client['dictionary'] self.words = self.db['words'] def insert_word(self, word_data): """插入或更新单词数据""" filter_ = {'word': word_data['word']} self.words.replace_one(filter_, word_data, upsert=True) def get_word(self, word): """查询单词数据""" return self.words.find_one({'word': word.lower()})

5. 高级技巧与异常处理

5.1 多义词处理策略

剑桥词典中多义词的页面结构更为复杂,需要特殊处理:

def handle_polysemy(soup): """处理多义词情况""" entries = [] main_entry = soup.find('div', class_='pr entry-body__el') if not main_entry: # 多义词情况 sense_blocks = soup.find_all('div', class_='pr dsense') for block in sense_blocks: headword = block.find('span', class_='hw dsense_hw') definition = block.find('div', class_='def ddef_d db') if headword and definition: entries.append({ 'variant': headword.text, 'definition': definition.text }) return entries

5.2 反爬规避实战方案

长期运行的采集系统需要更完善的反反爬策略:

class SmartRequest: def __init__(self): self.session = requests.Session() self.proxies = self._init_proxies() self.current_proxy = 0 self.last_request = 0 def _init_proxies(self): # 实现代理池初始化逻辑 return ['http://proxy1:port', 'http://proxy2:port'] def get(self, url): # 请求速率控制 elapsed = time.time() - self.last_request if elapsed < 2.5: # 保持合理间隔 time.sleep(2.5 - elapsed) try: proxy = {'http': self.proxies[self.current_proxy]} resp = self.session.get(url, proxies=proxy, timeout=10) if resp.status_code == 403: self._rotate_proxy() return self.get(url) self.last_request = time.time() return resp except: self._rotate_proxy() return self.get(url) def _rotate_proxy(self): self.current_proxy = (self.current_proxy + 1) % len(self.proxies)

6. 实战应用案例

6.1 构建离线单词本

将采集的数据转化为Anki记忆卡片:

def create_anki_card(word_data): """生成Anki导入格式数据""" front = f"<h1>{word_data['word']}</h1>" back = "<div class='definitions'>" for def_item in word_data['definitions']: back += f""" <div class='definition'> <span class='pos'>{def_item['pos']}</span> <p>{def_item['definition']}</p> {f"<blockquote>{def_item['example']}</blockquote>" if def_item['example'] else ""} </div> """ back += "</div>" # 添加发音按钮 if word_data['pronunciation'].get('uk'): back += f""" <audio controls> <source src="{word_data['pronunciation']['uk']}" type="audio/mpeg"> </audio> """ return [word_data['word'], front, back]

6.2 集成到翻译工具

将词典数据与翻译API结合:

class EnhancedTranslator: def __init__(self): self.db = DictionaryDB() self.cache = {} def lookup(self, word): # 先检查缓存 if word in self.cache: return self.cache[word] # 查询本地数据库 db_result = self.db.get_word(word) if db_result: self.cache[word] = db_result return db_result # 实时采集 url = f"https://dictionary.cambridge.org/dictionary/english/{quote(word)}" resp = safe_request(url) if resp: data = parse_word_page(resp.text) self.db.insert_word(data) self.cache[word] = data return data return None
http://www.cnnetsun.cn/news/3081555.html

相关文章:

  • 从纯文本政务 Agent 到具身交互智能:我用魔珐星云搭建大厅咨询数字人。
  • AI代码审查工具到底值不值得上?一线团队3个月实测数据揭示真实ROI与隐性成本
  • 别再只用交叉熵了!手把手教你用PyTorch实现Focal Loss解决样本不平衡(附完整代码)
  • 实战分享:用ShardingSphere 4.1.1搞定国际化多语言数据源切换(附完整代码)
  • 如何在云原生环境中使用DIM实现容器与虚拟机的动态完整性保护
  • 怎么使用AI 实现协作
  • 【企业级OVF交付标准】:从单机导出到跨云迁移,一套标准化流程覆盖ESXi 6.7–8.0全版本
  • 腾讯云服务器镜像到底怎么选?一篇给小白看的 CVM 镜像入门到实战指南
  • 电脑打开程序提示“为了对电脑进行保护,已经阻止此应用”
  • 【CFD理论】为什么需要壁面函数
  • Three.js 赛博朋克 UI 渲染:从着色器管线到后处理特效的 3D Web 实战
  • 2026完整版AI大模型学习路线!零基础小白/程序员从入门到落地全攻略
  • 如何在Vue项目中5分钟集成二维码生成功能:qrcode.vue完整指南
  • 告别重启!用Lsposed+Zygisk在Android 13上实现免重启热更新Hook(附完整Demo)
  • 实战:利用Playwright隐藏自动化特征(Stealth模式)的底层原理
  • 网站关键词如何优化?
  • 别再乱删了!Qt容器QList/QVector/QMap/QHash删除操作的性能陷阱与正确姿势
  • 终极ZIP工具套件utzip:一文了解utzip、utzipnote、utzipcloak与utzipsplit四大组件
  • AI算力调度方案评估指南:从原理到实践落地
  • Android GNSS HAL层接口全解析:从HIDL 1.0到厂商实现,一篇搞懂定位服务如何与硬件对话
  • 手机摄像头模组量产,为什么需要一个‘标准件’?聊聊Golden模组与OTP烧录那些事
  • 大语言模型微调技术:从全参数到 LoRA 的参数效率演进
  • HarmonyOS技术精讲-Form Kit(卡片开发服务)第2篇:搭建ArkTS卡片开发环境与创建第一个卡片
  • 别再乱用iPerf3的-P参数了!一个参数搞懂TCP/UDP打流瓶颈在哪
  • 魔珐星云 SDK 实战:从基础代码到具身交互终端成品
  • 门店私域客户管理升级:AI智能检索客户功能使用科普
  • MCP协议全面落地:AI Agent如何改变软件开发流程
  • 别再死记公式了!用PyTorch代码直观理解nn.Conv3d的参数量与计算量
  • 告别车载ECU耗电焦虑:手把手教你配置AUTOSAR NM的Partial Network功能
  • 让外贸网站询盘翻倍的新概念GEO,90%的技术人还没注意到