你遇到的真实场景
上周帮新加坡电商团队抓取日本乐天商品页时,突然发现价格显示成「ジューシー」这样的乱码;给德国客户做的爬虫在抓取俄语网站时,把西里尔字母识别成了问号框。这些就是跨语言数据提取的典型车祸现场。
编码识别:从乱码到可读文本的技术解剖
1. 浏览器自动化中的编码陷阱
Playwright默认使用UTF-8加载页面,但遇到这些情况会翻车:
- 日语Shift_JIS编码的 legacy 系统
- 西欧语言的ISO-8859-1历史页面
- 没有声明<meta charset>的中文网页
# 强制指定编码的实战代码
async with page.expect_response('**/*') as response_info:
await page.goto(url)
response = await response_info.value
raw_bytes = await response.body()
detected_encoding = chardet.detect(raw_bytes)['encoding'] # 使用chardet检测
html_content = raw_bytes.decode(detected_errors='ignore') # 安全解码
多语言文本提取的黄金法则
2. 语言检测的实用技巧
安装langdetect库时要注意这个坑:
pip install langdetect==1.0.9 # 避免新版出现的概率性问题
实战中推荐组合使用两种检测方式:
- 基于HTTP头部的Content-Language
- 基于TF-IDF的语言指纹比对
from langdetect import DetectorFactory
DetectorFactory.seed = 0 # 确保结果可复现
def safe_detect(text):
try:
return detect(text[:1000]) # 处理长文本时截断
except:
return 'unk'
避坑指南:我们踩过的那些雷
- 越南语会被误判为葡萄牙语(都是拉丁字符+大量变音符号)
- 中日韩混合页面建议先用CJK正则分割区块
- 当confidence值<0.7时应该人工复核
进阶方案:混合策略提升准确率
建议采用三级识别体系:
- 优先读取HTML的lang属性
- 检查<meta>标签声明
- 最终使用机器学习检测正文
graph TD
A[原始网页] --> B{有lang属性?}
B -->|Yes| C[直接采用]
B -->|No| D[检测meta标签]
D --> E{找到charset?}
E -->|Yes| F[按声明解码]
E -->|No| G[字节模式检测]
特殊字符的处理艺术
当遇到泰语、阿拉伯语等复杂文本时:
- 使用normalize()统一字符标准
- 注意Python的字符串操作会破坏组合字符
- 推荐专门库:
- arabic-reshaper(阿拉伯语连字)
- python-bidi(双向文本处理)
最佳实践清单
- 始终保存原始字节流作为备份
- 记录检测时的confidence值
- 针对特定语系编写fallback规则
- 建立常见错误映射表(如把「語」识别成日语实际是繁体中文)
有次帮客户处理哈萨克斯坦政府网站,发现西里尔字母和拉丁字母交替出现,最终通过字体反爬检测才解决。这类案例说明:真正的多语言环境往往比技术文档描述的更混沌,准备好你的瑞士军刀工具箱才是王道。