Python 2中urllib2中文乱码的本质是未正确识别或解码响应字符编码,需依次从响应头Content-Type、HTML meta标签提取charset,再按utf-8/gbk/gb2312顺序尝试解码,最后fallback为latin-1。

Python 2 中 urllib2 获取网页后出现中文乱码,本质是**未正确识别或解码响应的字符编码**。核心解决思路:先获取服务器声明的编码(如 Content-Type 中的 charset),再用该编码解码响应内容;若缺失或错误,则按 HTML meta 标签或常见默认编码(如 UTF-8、GBK)尝试解码。
检查并使用响应头中的 charset
服务器通常在 HTTP 响应头 Content-Type 中指定编码,例如 text/html; charset=utf-8。这是最优先采用的依据:
- 用
response.headers.get('content-type')提取 header 字符串 - 用正则或字符串方法提取
charset=xxx后的值(注意大小写和空格) - 用该编码对
response.read()的字节流进行.decode(charset)
解析 HTML 中的 meta charset(备用方案)
当响应头未提供或不可靠时,需读取 HTML 源码前几 KB,查找 或 等标签:
- 限制读取长度(如
response.read(5000)),避免下载整页 - 用正则
r']+charset[^\>]*>'匹配 meta 标签,再提取编码值 - 注意转义和大小写,推荐用
re.IGNORECASE
设置容错解码(兜底策略)
若前两种方式都失败,可按常见编码依次尝试解码,并捕获 UnicodeDecodeError:
立即学习“Python免费学习笔记(深入)”;
- 优先试
utf-8(现代网站主流) - 再试
gbk或gb2312(中文旧站常见) - 最后考虑
latin-1(能无损解码任意字节,但中文会乱,仅作调试用) - 用
try/except控制流程,成功即跳出
完整示例(含异常处理)
以下代码整合上述逻辑,适用于 Python 2.7:
import urllib2 import redef get_page_content(url): response = urllib2.urlopen(url) raw = response.read()
# 1. 从 headers 取 charset charset = None ct = response.headers.get('content-type', '') m = re.search(r'charset=([^\s;]+)', ct, re.I) if m: charset = m.group(1).strip('"\'').lower() # 2. 若 headers 没有,从 HTML meta 中找 if not charset: sample = raw[:5000].lower() m = re.search(r']+charset=([^">]+)', sample) if m: charset = m.group(1).strip() # 3. 尝试解码 for enc in [charset, 'utf-8', 'gbk', 'gb2312']: if not enc: continue try: return raw.decode(enc) except (UnicodeDecodeError, LookupError): continue # 4. 最终 fallback(不推荐用于显示,仅调试) return raw.decode('latin-1', 'replace')使用
html = get_page_content('https://www.php.cn/link/374cad868cb62202053d308252bc4040') print(html[:200])











