本文共 2233 字,大约阅读时间需要 7 分钟。
使用 Requests 库进行 HTTP 请求 时,可能会遇到中文网页乱码的问题。这种情况通常是由于编码识别不正确导致的。当响应头中没有明确指定字符集时,Requests默认使用 ISO-8859-1 编码,这可能无法正确显示中文内容,导致乱码现象。
Requests 库默认通过响应头的 Content-Type 字段获取编码信息。如果 Content-Type 中包含 charset 参数,会优先使用该编码;如果 Content-Type 为 text 类型且没有 charset,则默认使用 ISO-8859-1。然而,许多中文网页的响应头可能不包含 charset 或 Content-Type,导致 Requests 错误选择编码,进而引发乱码问题。
Requests 提供了多种方法来解决编码识别问题:
apparent_encoding 属性Response 对象提供了 apparent_encoding 属性,该属性使用 chardet 库检测响应内容的实际编码。这种方法能够更准确地识别网页的实际字符编码,特别适用于缺少 Content-Type 或 charset 的情况。
get_encodings_from_content 方法requests.utils.get_encodings_from_content 方法可以从响应内容中提取可能的字符编码。它通过查找 HTML 标签中的 charset meta 标签、content 标签或 XML 编码声明来确定可用的编码。
为了自动处理 ISO-8859-1 编码问题,可以使用 Monkey Patch 方法增强 Requests 的默认行为。以下是一个示例:
import requestsdef monkey_patch(): prop = requests.models.Response.content def content(self): _content = prop.fget(self) if self.encoding == 'ISO-8859-1': encodings = requests.utils.get_encodings_from_content(_content) if encodings: self.encoding = encodings[0] else: self.encoding = self.apparent_encoding _content = _content.decode(self.encoding, 'replace').encode('utf8', 'replace') self._content = _content return _content requests.models.Response.content = property(content)monkey_patch() 这个 Monkey Patch 会在响应内容被访问时,检查当前编码是否为 ISO-8859-1。如果是,则通过 get_encodings_from_content 进行编码检测,并将结果设置为新的编码。如果检测到多个编码,优先使用 apparent_encoding 作为备选方案。
以下是一个使用 Requests抓取中文网页的实际示例:
import requests# 正常抓取示例r = requests.get('http://cn.python-requests.org/en/latest/')print(r.encoding) # 输出: ISO-8859-1print(r.apparent_encoding) # 输出: utf-8print(requests.utils.get_encodings_from_content(r.content)) # 输出: ['utf-8']# 使用 Monkey Patch 之后r = requests.get('http://reader.360duzhe.com/2013_24/index.html')print(r.encoding) # 输出: gb2312print(r.apparent_encoding) # 输出: gb2312print(requests.utils.get_encodings_from_content(r.content)) # 输出: ['gb2312'] 通过 Monkey Patch,Response 对象会在 ISO-8859-1 编码下自动检测并设置正确的编码,避免了乱码问题。
通过合理利用 Requests 提供的编码检测功能,并在必要时使用 Monkey Patch 增强默认行为,可以有效解决中文网页乱码问题。建议在开发过程中,根据实际需求选择合适的编码检测方法,确保数据正确解析和显示。
转载地址:http://jgofk.baihongyu.com/