好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 DreamMark 于 2024-5-23 15:15 编辑
前言
昨天遇到一个requests相关问题, 在本地get请求时没有问题。 但是,在线上服务器请求返回却是乱码。 在对比环境后发现,同样得python 环境,包版本,都是一样的, 但是线上的就是返回乱码。
抓包, 查看requests 发出的请求有什么问题。Requests 被抓包 报SSLError?- 加个 verify=False
- 没解决? 修改下相关包的版本
- Requests 相关包:incremental ,urllib3 ,certifi ,cryptography,pyOpenSSL
- 一般来说, 安装requests , 如果没有certifi , 它会自动安装
- pip install requests==2.19.1
- pip install incremental
结果? 很正常没有任何问题。 抓包软件,编码正常。 Requests 返回乱码这。。。编码问题啊。
分析requests一般来说我们使用 requests 时, 通过两种方法拿到响应的内容:
- response.content (返回str)
- response.text (返回byte)
阅读requests 源码可以看到, response.text 是以 response.content (字节码) 和 encoding (编码) 为根据, 将字节码转换成 str 返还给我们的.换句话说就是, response.text 自动帮我们把从服务器获得的字节流转换成 str 返还给我们, 为我们减去了各种网页编码带来的 “乱码” 的问题.那么为什么 response.text 仍然有时候会出现乱码的问题呢?首先, requests 在计算 response.text 的时候, 会先看响应的 http header 中是否提供了 encoding 信息. 我们通过 response.encoding 可以拿到这个值。按理来说, 网页已经告诉我们, 它用的是那个编码, 于是 requests 就信以为真, 拿 编码来解析字节流, 转换为字符串, 于是我们就看到 response.text 的乱码了 - 问题就出在, 网页告诉了爬虫一个错误的编码信息。那么我们提出新的思路, 如果我们不使用 http header 提供的 encoding, 而采用其他方法获知 encoding 有没有可能呢?requests 确实有此方法, 不过是在 http header 提供的 encoding 为 None 时才会用. 它通过 chardet (一个 Python 第三方模块, 用来预测文件编码) 来检测网页最可能用的是哪种编码. 注意这里是 “可能用的”, 因为 chardet 的原理就是用各种编码来试, 直到找出一个看起来不像是乱码的情况。我们通过 response.apparent_encoding 可以拿到这个值。
查看下返回什么
调用 response.apparent_encoding ,
无语的出现了 尽然返回None , 这就难搞了 。
我们看下 response.headers['content-encoding']) , 返回 gzip,deflate,br,zstd ,注意看下有没有空格, requests 早期版本, 有空格是不认的, 当然新版本已经支持了。
这么多压缩, 我们把压缩都去掉看看。
可以返回正常了,,,,那问题很明确了, 出在压缩这里, 里面至少有一种压缩格式, 服务器环境是没法解压缩的。
控制下变量测下, 是br 压缩方法 (Brotli 算法 2015 年 9 月 Google 推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压塑压缩效率。启用 Brotli 压缩算法,对比 Gzip 压缩 CDN 流量再减少 20%。)。
解决方式
请求头去掉br , 完美 。 可以正常访问了。 对比下, 大概率是服务器装的 win 版本太老旧 导致的。。。 这无妄之灾啊。。。
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|