resp.text
工作原理: requests 库会尝试根据 HTTP 响应头中的 Content-Type(例如 text/html; charset=utf-8)或通过 Chardet 库自动猜测响应内容的编码。然后,它会将原始的字节内容自动解码成 Unicode 字符串。
优点:方便快捷: 大多数情况下,这是获取文本内容最直接、最方便的方式,无需手动处理编码。
自动编码检测: 能够智能地处理多种编码情况。
缺点:
可能出现乱码: 如果 requests 自动检测到的编码不正确,或者响应头中没有明确指定编码,就可能出现乱码问题。
选择:
- 当您确定响应内容是文本(如 HTML、JSON、XML、纯文本等),并且
requests能够正确识别其编码时,这是最推荐和最方便的方式。 - 快速获取文本: 如果您只是想快速查看响应内容,不关心具体的编码细节,可以先尝试
resp.text。
首选resp.text,乱码时考虑resp.content.decode()
如果是内容确定的页面, resp.content.decode(encoding) 中的encoding 可以通过chardet手动获取一下,然后把结果硬编码到 resp.content.decode(“通过chardet获取的编码”)中,例如chardet.detect(res.content)['encoding'] 得到的是“gbk”,那么就直接硬编码resp.content.decode('gbk')
======================
如果想尽量一招通杀,例如直接在写日志的函数中,可以
log_txt = resp.content.decode(cchardet.detect(resp.content)['encoding'])如果在传给写日志函数前就将resp.encoding属性设置好,就更佳了。
# 如果已知 resp.text 无乱码, 可以什么都不做 # 如果已知 'utf-8' 可以解决乱码,则可写: resp.encoding='utf-8' # 如果未知,则 resp.encoding = cchardet.detect(resp.content)["encoding"] # 然后统一用 resp.text log_txt=resp.text======================
使用requests模块请求网页内容,经常会出现乱码,例如:
import requests res = requests.get("https://www.baidu.com/") print(res.text)乱码的原因是内容编码和解码方式不一致导致的,解决办法有以下几种解决办法:
第一种:apparent_encoding
import requests res = requests.get("https://www.baidu.com/") res.encoding = res.apparent_encoding print(res.text)另有解释:
r.encoding是直接套用response的charset字段,如果response没有charset,那么r.encoding 就会不管三七二十一,想当然地设为'ISO-8859-1',这种情况下r.encoding不值得信任。
所以,先判断r.encoding是否等于'ISO-8859-1',如果是再用 r.apparent_encoding替换,感觉这样应该更好:
if r.encoding == 'ISO-8859-1': r.encoding = r.apparent_encoding;我们看看官方源代码:
具体来看r.encoding和r.apparent_encoding的值是怎么来的
(1)先说r.encoding
response.encoding = get_encoding_from_headers(response.headers)
https://github.com/requests/requests/blob/d55de2d391d1350766221ce0aa36e670dc2a0169/requests/adapters.py#L273
(2)再说r.apparent_encoding
chardet.detect(self.content)['encoding']#调用了chardet模块的detect方法,参数给的是r.content
https://github.com/requests/requests/blob/d55de2d391d1350766221ce0aa36e670dc2a0169/requests/models.py#L719github.com/requests/requests/blob/d55de2d391d1350766221ce0aa36e670dc2a0169/requests/models.py#L719
可以知道,r.apparent_encoding是否准确,其实就是看chardet.detect是否准确。
第二种:content utf-8解码
一种临时性的解决办法,不建议用这种方法,相当于写死代码了。
import requests res = requests.get("https://www.baidu.com/") try: txt = res.content.decode('gbk') except UnicodeDecodeError as e: # print(e) txt = res.content.decode('utf-8') print(txt)第三种:chardet
import requests import chardet res = requests.get("https://www.baidu.com/") encoding = chardet.detect(res.content)['encoding'] print(res.content.decode(encoding))第四种:cchardet
cchardet需要提前安装一下:pip install cchardet。
import requests import cchardet res = requests.get("https://www.baidu.com/") encoding = cchardet.detect(res.content)['encoding'] print(res.content.decode(encoding))chardet和cchardet的区别:cchardet是chardet的一个加速版本,使用了C语言实现,因此性能更高
chardet和cchardet都是 Python 库,用于字符编码检测,主要用于确定文本数据的字符编码格式(如UTF-8、ISO-8859-1等),以便正确地解析和处理文本数据。它们之间的主要区别在于性能和实现语言。
chardet:chardet是一个用 Python 编写的字符编码检测库。- 它的性能相对较慢,因为它是一个纯Python库,不是特别适合处理大型文本数据。
chardet基于统计模型和启发式算法,通过分析字符的分布和出现频率来猜测文本的编码。- 你可以使用
chardet安装它,通常是通过pip:pip install chardet。
cchardet:cchardet是chardet的一个加速版本,使用了C语言实现,因此性能更高。- 由于它是用C编写的,所以在处理大型文本文件时速度更快,适用于需要高性能字符编码检测的应用。
cchardet通常被认为是chardet的替代品,可以无缝替代chardet,因为它提供了相同的接口。- 你可以使用
cchardet安装它,通常是通过pip:pip install cchardet。
总之,如果你需要进行字符编码检测并且对性能有较高要求,可以考虑使用cchardet。如果性能不是首要考虑因素,或者你需要在某些环境中使用纯Python库,那么chardet仍然是一个不错的选择。
第五种:encode + decode
import requests import cchardet res = requests.get("https://www.baidu.com/") res_encoding = res.encoding # 响应的编码方式 con_encoding = cchardet.detect(res.content)['encoding'] # 内容的编码方式 print(res.text.encode(res_encoding).decode(con_encoding)) # 重新编解码text