Python3 下读取 .txt 文件中文乱码问题如何解决?
基本情况: Vultr $2.5/year, CentOS 7, 安装的是 Python3.6。
@app.route("/douban", methods=['GET'])
def doubanFM():
f = open('douban.txt', 'r')
txt = f.read()
lines = txt.split('#\n')
lines = lines[:-1]
return random.choice(lines)
用 Python3.6 运行上面的代码,出现错误。其中,douban.txt 文件中大都为中文字符,.py 文件开头加了 #coding:utf-8。主要错误代码如下:
...
...
File "/usr/lib64/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib64/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/root/weather/app.py", line 32, in DoubanFM
txt = f.read()
File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
后来没办法换用 CentOS 自带的 Python2 运行,没错误,能正常输出中文。但我很想知道为啥用 Python3.6 来运行就不行,求相应解决办法。
Python3 下读取 .txt 文件中文乱码问题如何解决?
.py 文件声明的事你脚本的编码方式,和你操作的文件没有关系。
file douban.txt 看一下编码方式。
https://i.loli.net/2017/08/23/599d33d15ced5.png
遇到.txt文件中文乱码,通常是文件编码和读取编码不匹配导致的。直接上代码,最稳的解决方案是先用chardet库检测编码,再用检测到的编码去读取。
首先,安装检测库:
pip install chardet
然后,用这个脚本来读文件:
import chardet
def read_txt_file(file_path):
# 先用二进制模式读取一部分字节来检测编码
with open(file_path, 'rb') as f:
raw_data = f.read(10000) # 读前10000字节通常足够检测
result = chardet.detect(raw_data)
encoding = result['encoding']
confidence = result['confidence']
print(f"检测到编码: {encoding} (置信度: {confidence:.2%})")
# 用检测到的编码重新打开文件
try:
with open(file_path, 'r', encoding=encoding) as f:
content = f.read()
return content
except UnicodeDecodeError:
# 如果检测的编码不对,尝试常见的中文编码
for enc in ['utf-8', 'gbk', 'gb2312', 'gb18030']:
try:
with open(file_path, 'r', encoding=enc) as f:
content = f.read()
print(f"使用备用编码 {enc} 成功读取")
return content
except UnicodeDecodeError:
continue
raise ValueError("无法用常见编码读取文件")
# 使用示例
file_path = 'your_file.txt'
content = read_txt_file(file_path)
print(content[:500]) # 打印前500字符看看
如果不想装chardet,或者知道文件大概是什么编码,可以直接试这几个常见的中文编码:
encodings = ['utf-8', 'gbk', 'gb2312', 'gb18030']
content = None
for enc in encodings:
try:
with open('your_file.txt', 'r', encoding=enc) as f:
content = f.read()
break
except UnicodeDecodeError:
continue
if content:
print(content)
关键就一点:文件保存的编码和open()里指定的encoding参数必须一致。Windows系统下创建的.txt文件经常是gbk(或gb2312、gb18030),而Linux/macOS或现代编辑器默认多是utf-8。用上面代码检测或轮询一遍基本能解决。
总结:用工具检测或手动试常见编码。
‘ascii’ codec can’t decode byte 0xe6
f = open(‘douban.txt’, ‘r’, encoding="utf-8)
# 试一下
可以的,谢谢~
f.close()
请教下: 如果不关闭文件影响大不大?如果我用 with open(‘douban.txt’, ‘r’, encoding="utf-8) 是不是不用关了
代码执行到 with 范围以外会自己关闭文件
首先, 的答案 +1。
感觉跟我之前遇到的问题类似,我估计你 用 open(‘douban.txt’, ‘r’, encoding="utf-8) 之后,然后 read() 出来数据;我估计你打印(print)的时候也会报错。
你 3.6 自己编译安装的吧? 安装后有升级过 系统的 C 库么?
with 会自动关
print 的时候报不报错取决于终端的使用的编码吧,和代码就没啥关系了吧。
尽量都用 with open… as …来打开文件。
我所指的报错是 python raise Exception。系统遇到打印不出来的字符是会用[乱码]形式展现不会报错。
当 python 无法正确推断 sys.stdout.encoding 时可能会报错,比如它将该 encoding 错误推断成 ascii 就会在最后对 > 127 的字节码 报错。
哈哈哈…最近看来开始折腾 douban 的人增加了
我那时是按照 DO 上的这篇 [文章]( https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-centos-7) 在 CentOS 上安装 Python3.6 的,这样可以吗
写个最简单的文件,看看你 VPS 上的 Python3 能不能执行:python<br>#coding: utf-8<br><br># 中文注释<br>print("中文哟")<br>
不能的话,估计是你 Python3 安装得有问题,建议更换为 pyenv
运行后,确实出错了。我明天重装看看~~<br>Traceback (most recent call last):<br> File "<a target="_blank" href="http://zz.py" rel="nofollow noopener">zz.py</a>", line 4, in <module><br> print("\u4e2d\u6587\u54df")<br>UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)<br>
可能跟你 python 安装得方式无关。
也有可能是的 VPS 系统语言设置得不对。用 locale 命令查看下,本地化得设置, 确认是否为 UTF-8(特别是 LC_CTYPE=xxx.UTF-8)。
如果你自己升级过 c 库,就很有可能出问题。这时你可能直接设置不回来 LC_CTYPE=xxx.UTF-8, 可以 参照 https://my.oschina.net/VASKS/blog/659236 去 yum reinstall glibc-common 看看。这个问题我也 hold 不住,各种坑要详细一步步解才行。
最后还有一个简便得解决方案就是,设定 python 的 encoding 的环境变量(PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.)。
e.g.export PYTHONIOENCODING=utf-8
或者 你将此变量保存到 ~/.bashrc 中吧。
文件失效了?
谢谢回复。
1、locale 后返回都是 UTF-8 ;
2、c 库我没明确升级过。VPS 较新,只装 oneinstack,不知道对 c 库有没有影响;
3、设置并保存 ~/.bashrc 后,可以了 😄
那是传到火狐 send 上的。新的: https://file.ni-co.moe/M8B2iojB44YciAJQNjY9bOCEcCVy0BYW.txt


