[434]UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\ufffd‘等类似问题

本文主要是介绍[434]UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\ufffd‘等类似问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 问题描述
      • 错误原因
      • 解决办法
      • 解决过程
        • 使用Python自带的集成开发环境IDLE
      • 最终解决
      • 常用中文编码名称

问题描述

在写爬虫爬取网页信息时,发生了以下错误:

UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\ufffd’

意思大致是Unicode编码错误,gbk编解码器不能编码\ufffd字符。

错误原因

  • cmd默认编码是GBK,字符\ufffd不能编码为GBK。

  • 查阅Unicode编码表或者使用Python自带的集成开发环境IDLE(可以输出),可知\ufffd其实是�字符。

  • Python3的字符串以Unicode编码,也就是解析网页时,需要将字符串从网页原来的编码格式转化为Unicode编码格式。

  • 出现�字符的原因:从某编码向Unicode编码转化时,如果没有对应的字符,得到的将是Unicode的代码\ufffd,也就是�字符。

  • 在写爬虫解析网页时出现�字符,往往是因为没有注意原网页的编码格式,全按照默认编码UTF-8转化,导致有的字符转化失败。

在本问题中,是由于在网页上包含珺、玥这样的中文,由于珺、玥是生僻字没有相应的UTF-8编码,所以以默认UTF-8编码格式转化为Unicode时,没有对应的字符,转化出错,得到\ufffd。又因为在cmd运行,因此报错UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\ufffd’。

解决办法

写爬虫解析网页时,要注意原网页的编码格式和压缩格式(Gzip等)

查看原网页的编码格式,为’gb2312’。

所以要按照gb2312编码向Unicode编码转化。

r = requests.get(url,cookies=cookies,headers=headers)
# 指定网页的编码格式
r.encoding = 'gbk'
# r.encoding = 'gb2312' 仍然会报错

最后再次在cmd运行代码,这样的中文也成功显示。

注意:本解决办法适用于与本问题描述完全相同的问题,因为可能是相同的错误原因导致的。其它报错信息可能与本问题的情况不同,比如报错的为‘gbk’ codec can’t encode character ‘\xa0’

以下是问题的逐步分析解决过程。

解决过程

cmd显示编码是GBK,而有些Unicode字符不能编码成GBK

对于Unicode字符,需要print出来的话,由于本地系统是Windows中的cmd,默认codepage是CP936,即GBK的编码,所以python解释器需要先将上述的Unicode字符编码为GBK,然后再在cmd中显示出来。但是由于该Unicode字符串中包含一些GBK中无法显示的字符,导致此时提示'gbk' codec can’t encode的错误的。

分析:这个解释确实符合报错信息’gbk’ codec can’t encode character '\ufffd’的意思。

验证:编写python代码

print('\ufffd')

在cmd下运行,出现相同的报错信息'gbk' codec can't encode character '\ufffd'

解决办法1:改变标准输出的默认编码

在程序的开始加入以下代码

import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') 

由于我输出的包含中文,所以使encoding=‘gb18030’,这段代码的作用就是把标准输出的默认编码修改为gb18030,也就是与cmd显示编码GBK相同。

效果:运行原来的爬虫代码后,没有了报错,但原先报错的输出位置显示为??,中文仍没有正确显示。

image.png

而且还有不能即时输出的问题,类似于python爬虫中文输出问题以及不即时输出问题

解决办法2:输出时忽略无法编码的字符

在对Unicode字符编码时,添加ignore参数,可以忽略无法编码的字符

print(你的字符串.encode('GBK', 'ignore').decode)

这句代码的作用为,把字符串以GBK编码,并忽略无法编码的字符,再以GBK解码,再输出。

效果:在解决办法1的效果基础上,??不再显示,但中文仍没有正确显示。

image.png

总结:由于\ufffd本身就没有对应的Unicode编码,所以要在cmd中不报错输出,只能把输出编码改为GBK或者在输出时忽略无法编码的字符,这样就算可以不报错输出,也不能正确显示\ufffd字符。

使用Python自带的集成开发环境IDLE

cmd的显示编码是GBK,要想正确显示\ufffd字符,就要使用支持多种输出编码的运行环境。Python自带的集成开发环境IDLE就对GBK、UTF-8、Unicode都支持。其实,Pycharm、jupyter notebook、sublimeREPL配置的python运行环境也支持多种输出编码。

IDLE打开方法:在python的安装目录下,打开lib/idlelib/idle.bat,就进入了IDLE环境

运行代码

print('\ufffd')

输出为: �

看到�这个结果,开始以为仍没有正确显示。但查询Unicode字符表,发现�字符的Unicode的值正是fffd。说明\ufffd字符已经正确显示了。

进一步分析

以上分析的原因和解决办法都是从最后显示输出的角度去考虑的,虽然一些方法不再报错,但仍然显示不正确,并没有真正解决。然后在IDLE中正确显示了字符,证明了\ufffd就是�字符。

从以上解决办法可以进一步验证和推测一些问题:

问题

  • 本来应该显示的汉字是什么
  • �是从哪来的

推测
对照原网页,发现是珺和玥字没有正确显示,而变成了\fffd�字符。这说明从一开始解析网页,珺和玥就被解析成了�字符。

验证
如果从报错信息找问题,报错原因是部分Unicode字符不能正确转码成GBK,所以无法显示。根据推测,原网页上的珺和玥字没有正确显示,而运行以下代码:

str = '珺玥'
str = str.encode('unicode_escape')
print(str)
# 输出 b'\\u73fa\\u73a5'

可知的Unicode分别为73fa73a5。而不是fffd

经验证,print(’\u73a5’)是可以输出的玥字的。这说明并不是玥的Unicode转码为gbk失败,而是解析玥得到的Unicode都不正确,变成了\ufffd�字符。

使用爬虫 �作为关键字搜索,就找到了出现�字符的原因:

从某编码向Unicode编码转化时,如果没有对应的字符,得到的将是Unicode的代码“\uffffd”,也就是�这个字符。这个是你的爬虫根本不识别原网页的编码格式(ASCII或者GB2312等)和压缩格式(Gzip等),全都无脑转成UTF-8字符串导致的,出现这个字符说明转换失败,数据已经丢失了,这个字符本身并没什么实际意义。

最终解决

在进一步分析后,重新检查解析过程,显然是编码问题。

最后发现确实是因为没有注意到网页编码问题,网页编码是gb2312,而用requests请求的网页,如果不声明encoding值,默认是用UTF-8解析的。UTF-8编码支持大部分中文字,但不支持珺、玥这样的生僻字,这样转成UTF-8就转化失败。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1dWPllds-1631098910407)(https://upload-images.jianshu.io/upload_images/12504508-32440461df09d704.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

原网页的编码格式为’gb2312’
所以要按照gb2312编码向Unicode编码转化:

r = requests.get(url,cookies=cookies,headers=headers)
# 指定网页的编码格式
r.encoding = 'gbk'
# r.encoding = 'gb2312' 仍然会报错

最后再次在cmd运行代码,珺、玥这样的中文也成功显示。

最终总结,是由于在网页上包含珺、玥这样的中文,由于珺、玥是生僻字没有相应的UTF-8编码,所以以默认UTF-8编码格式转化为Unicode时,没有对应的字符,转化出错,得到\ufffd。又因为在cmd运行,因此报错UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

常用中文编码名称

编码名称用途
utf8所有语言
gbk简体中文
gb2312简体中文
gb18030简体中文
big5繁体中文
big5hkscs繁体中文

来源:https://blog.csdn.net/qq_38607035/article/details/82595032
https://blog.csdn.net/jim7424994/article/details/22675759

这篇关于[434]UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\ufffd‘等类似问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6

问题-windows-VPN不正确关闭导致网页打不开

为什么会发生这类事情呢? 主要原因是关机之前vpn没有关掉导致的。 至于为什么没关掉vpn会导致网页打不开,我猜测是因为vpn建立的链接没被更改。 正确关掉vpn的时候,会把ip链接断掉,如果你不正确关掉,ip链接没有断掉,此时你vpn又是没启动的,没有域名解析,所以就打不开网站。 你可以在打不开网页的时候,把vpn打开,你会发现网络又可以登录了。 方法一 注意:方法一虽然方便,但是可能会有

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementui--$message提示框被dialog遮罩层挡住问题解决

最近碰到一个先执行this.$message提示内容,然后接着弹出dialog带遮罩层弹框。那么问题来了,message提示框会默认被dialog遮罩层挡住,现在就是要解决这个问题。 由于都是弹框,问题肯定是出在z-index比重问题。由于用$message方式是写在js中而不是写在html中所以不是很好直接去改样式。 不过好在message组件中提供了customClass 属性,我们可以利用

Visual Studio中,MSBUild版本问题

假如项目规定了MSBUild版本,那么在安装完Visual Studio后,假如带的MSBUild版本与项目要求的版本不符合要求,那么可以把需要的MSBUild添加到系统中,然后即可使用。步骤如下:            假如项目需要使用V12的MSBUild,而安装的Visual Studio带的MSBUild版本为V14。 ①到MSDN下载V12 MSBUild包,把V12包解压到目录(

YOLO v3 训练速度慢的问题

一天一夜出了两个模型,仅仅迭代了200次   原因:编译之前没有将Makefile 文件里的GPU设置为1,编译的是CPU版本,必须训练慢   解决方案: make clean  vim Makefile make   再次训练 速度快了,5分钟迭代了500次

Pycharm配置conda环境(解决新版本无法识别可执行文件问题)

引言: 很多小伙伴在下载最新版本的pycharm或者更新到最新版本后为项目配置conda环境的时候,发现文件夹目录中无法显示可执行文件(一般为python.exe),以下就是本人遇到该问题后试验和解决该问题的一些方法和思路。 一般遇到该问题的人群有两种,一种是刚入门对pycharm进行conda环境配置的小白(例如我),不熟悉相关环境配置的操作和过程,还有一种是入坑pycharm有段时间的老手