来自于一篇【关于Python的requests中text中文乱码的问题】的思考?

2024-06-09 00:58

本文主要是介绍来自于一篇【关于Python的requests中text中文乱码的问题】的思考?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:使用requests做http协议的接口请求时,对响应结果text的编码问题:出现中文乱码,如何处理中文输出?

实践:请求百度!

import requestsdo_http=requests.session()
res=do_http.request('get','http://www.baidu.com')print(res.text)

结果输出如下:<title>ç¾åº¦ä¸ä¸ï¼ä½ å°±ç¥é</title>,这是百度的title

分析原因:网上说的一堆,比较繁琐,无非就是什么先encode再decode,那你为什么不用content属性呢?非得text?先看response.content属性的源码,它是响应报文的二进制编码,如果获取响应的encoding是None(实现原理:根据请求去检查响应报文content-type中匹配拆分是否有charset字段,如果没有就使用chardet猜一个编码值,百度网页的默认编码是'utf-8':

"""Content of the response, in unicode.If Response.encoding is None, encoding will be guessed using``chardet``.The encoding of the response content is determined based solely on HTTPheaders, following RFC 2616 to the letter. If you can take advantage ofnon-HTTP knowledge to make a better guess at the encoding, you shouldset ``r.encoding`` appropriately before accessing this property."""# Try charset from content-type

所以print(res.encoding)必然输出:IOS-8859-1,下面解释为什么不是utf-8?

分析requests的源代码发现,r.text返回的是处理过的Unicode型的数据,而使用r.content返回的是bytes型的原始数据。
也就是说,r.content相对于r.text来说节省了计算资源,r.content是把内容bytes返回. 而r.text是decode成Unicode. 
如果headers没有charset字符集的化,text()会调用chardet来计算字符集,这又是消耗cpu的事情.

那么如何来解决这个text编码的问题呢?从源码得知requests的默认编码是:IOS-8859-1,不懂?没关系,作者也不懂!(Latin-1或者叫西欧语言),requests请求时上面说了会去拿网页的编码,如果没有就使用自己chardet计算出来的。

但是很奇怪,明明得知自己访问的网站编码格式是utf-8,为什么输出还是requests自身的编码?即使是content也得不到正确的中文(下一篇我们再来看其中的源码关键)。

所以为了解决上面的问题,不得不通过encoding来改变它:res.encoding='utf-8',这时content正确了,text的问题仍没有解决?

前面又说了,text是编码后的unicode,所以要反过来编码encode一下,再解码decode,得到中文输出,代码如下:

# 使用requests库发起http请求,遇到字符编码的问题
import requestsdo_http=requests.session()
res=do_http.request('get','http://www.baidu.com')
# 每个网址使用的字符编码不一定相同,所以需要事先查看源码:charset=utf-8还是gbk,如果是gbk再使用encoding是会报错的
res.encoding='utf-8' # 网页是啥编码这里就是啥编码
# 网上也有一些解决办法:先decode再encode,然而貌似并可行,所说的应该适用于content这个属性
# print(res)
# print(res.status_code)
# print(res.content.decode())
# 编码再解码
print(res.text.encode().decode())

tips:这里调用编码解码的方法我使用了其自带的默认参数:encoding=utf-8,所以看到的是空括号。

这下结果可以正常输出:<title>百度一下,你就知道</title>

**日拱一卒无有尽,功不唐捐终入海!**

这篇关于来自于一篇【关于Python的requests中text中文乱码的问题】的思考?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043813

相关文章

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

Python极速搭建局域网文件共享服务器完整指南

《Python极速搭建局域网文件共享服务器完整指南》在办公室或家庭局域网中快速共享文件时,许多人会选择第三方工具或云存储服务,但这些方案往往存在隐私泄露风险或需要复杂配置,下面我们就来看看如何使用Py... 目录一、android基础版:HTTP文件共享的魔法命令1. 一行代码启动HTTP服务器2. 关键参

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali