Python Requests编码问题解决方案

在使用python requests时,有时会出现编码错误的问题,导致的主要原因是编码识别出错了。当获取到的内容出现乱码时,最常出现的错误是将编码识别成了ISO-8859-1。

ISO-8859-1是什么?

ISO 8859-1,正式编号为ISO/IEC 8859-1:1998,又称Latin-1或“西欧语言”,是国际标准化组织内ISO/IEC 8859的第一个8位字符集。它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入96个字母及符号,藉以供使用附加符号的拉丁字母语言使用。

为什么会被识别成ISO-8859-1?

通过出错的页面,我们发现在HTML中已经指明了页面具体的编码还是会出错。

具体原因是?通过查看源码,可以发现默认的编码识别比较简单,直接从响应头文件的Content-Type里获取,如果存在charset,则可以正确识别,如果不存在charset但是存在text就认为是ISO-8859-1,见Lib\site-packages\requests\utils.py。

可以看到,requests会先去找HTTP头部的“Content-Type”字段,如果没有,就调用“charade”来猜测编码。而默认的编码格式正是“ISO-8859-1”。代码中并没有去获取HTML页面中指定的编码格式,关于这样的处理,很多人也在官方的issues中提交了吐槽,但是作者回复是严格http协议标准写这个库的,HTTP协议 RFC 2616中提到,如果HTTP响应中Content-Type字段没有指定charset,则默认页面是’ISO-8859-1’编码。

When you receive a response, Requests makes a guess at the encoding to use for decoding the response when you call the Response.text method. Requests will first check for an encoding in the HTTP header, and if none is present, will use charade to attempt to guess the encoding.

The only time Requests will not do this is if no explicit charset is present in the HTTP headers and the Content-Type header contains text. In this situation, RFC 2616 specifies that the default charset must be ISO-8859-1. Requests follows the specification in this case. If you require a different encoding, you can manually set the Response.encoding property, or use the raw Response.content.

乱码解决方案

如果你知道明确的编码,解决方案非常简单,只需指定具体的编码即可。

当不清楚具体编码的情况下,如何获取准确的页面编码?

其实Requests提供了从内容获取编码,只是在默认中没有使用,见Lib\site-packages\requests\utils.py:

另外还提供了使用chardet的编码检测,见models.py:

针对这三种方式,识别编码的速率及需要的资源不同。

执行结果

最终解决方案,Python2,创建一个requests_patch.py文件,并在代码使用前import它,问题即可解决:

上述代码在Python3 下执行会报如下错误:TypeError: cannot use a string pattern on a bytes-like object,主要原因是python3中.content返回的非字符串数据。想在Python下获取正确的编码,具体代码如下:

微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode

使用Python检测符号及乱码字符

最近在进行关键词的分析,中间涉及到对一些特殊的字符进行过滤的需求。包括带符号的(有部分还是SQL注入),并且存

PHP版本升级记录(7.0到7.4)

服务器上原先安装的版本为PHP 7.0.33, WordPress后台建议安装的最小版本为7.3,所以打算直接

WordPress LaTeX插件更换记录

由于自己的博客要插入很多的公式,所以需要依赖LaTeX插件来帮忙实现。先前一直使用的是WP QuickLaTe

发表评论

电子邮件地址不会被公开。 必填项已用*标注