影刀RPA 编码问题的彻底解决:乱码一劳永逸

📅 2026/7/22 4:04:34
影刀RPA 编码问题的彻底解决:乱码一劳永逸
影刀RPA 编码问题的彻底解决乱码一劳永逸作者林焱做RPA的人几乎都遇到过乱码采集的中文变成??或者\u5f20\u4e09读CSV文件全是乱码写入Excel中文显示为问号控制台输出中文报错。这篇文章不讲编码理论只讲怎么彻底消灭乱码——从文件读写到网络请求到控制台输出一套方案全搞定。一、什么情况用什么乱码场景根本原因解决方案读CSV文件乱码文件编码不是UTF-8用chardet检测编码写Excel乱码openpyxl默认不支持确保数据是str类型网页采集乱码编码检测错误用requests的encodingJSON中文变\uXXXXjson.dumps没加参数ensure_asciiFalse控制台输出乱码Windows终端用GBK设置PYTHONIOENCODING文件名乱码系统编码不支持用unicode路径数据库乱码连接没指定charsetcharset‘utf8mb4’二、怎么做2.1 文件读写编码黄金法则所有文件读写都指定 encoding‘utf-8’# 读文件withopen(data.txt,r,encodingutf-8)asf:contentf.read()# 写文件withopen(output.txt,w,encodingutf-8)asf:f.write(中文内容)# 追加写入withopen(log.txt,a,encodingutf-8)asf:f.write(新的一行\n)不知道文件编码时——自动检测拼多多店群自动化报活动上架importchardetdefdetect_and_read(file_path):自动检测编码并读取文件# 先读取前10000字节检测编码withopen(file_path,rb)asf:raw_dataf.read(10000)resultchardet.detect(raw_data)encodingresult[encoding]confidenceresult[confidence]print(f检测到编码:{encoding}(置信度:{confidence:.1%}))# 用检测到的编码读取withopen(file_path,r,encodingencoding)asf:contentf.read()returncontent# 常见编码检测结果# UTF-8 → confidence 0.99# GBK → confidence 0.99# GB2312 → confidence 0.99# ASCII → confidence 1.0处理BOM头问题Windows的记事本保存UTF-8文件时会加BOM头\ufeff读取时开头会多一个不可见字符# 方法一用utf-8-sig编码自动处理BOMwithopen(data.txt,r,encodingutf-8-sig)asf:contentf.read()# utf-8-sig 会自动去除BOM头# 方法二手动去除BOMwithopen(data.txt,r,encodingutf-8)asf:contentf.read()ifcontent.startswith(\ufeff):contentcontent[1:]# 写入时不加BOM默认就不加withopen(output.txt,w,encodingutf-8)asf:f.write(内容)# 如果需要加BOM兼容某些旧软件withopen(output.txt,w,encodingutf-8-sig)asf:f.write(内容)2.2 CSV文件编码CSV是乱码重灾区不同来源编码不同importcsvimportchardetdefread_csv_auto_encoding(file_path):自动检测编码读取CSV# 检测编码withopen(file_path,rb)asf:rawf.read(10000)encodingchardet.detect(raw)[encoding]# 有些检测结果是GB2312实际应该用GBKifencodingGB2312:encodingGBKprint(f使用编码:{encoding})# 读取CSVwithopen(file_path,r,encodingencoding)asf:readercsv.DictReader(f)rowslist(reader)returnrows# 用pandas读取更简单importpandasaspddefread_csv_pandas(file_path):用pandas读取CSV自动处理编码encodings[utf-8,utf-8-sig,gbk,gb2312,big5,latin1]forencodinginencodings:try:dfpd.read_csv(file_path,encodingencoding)print(f成功读取编码:{encoding})returndfexceptUnicodeDecodeError:continue# 都失败了用chardet检测withopen(file_path,rb)asf:rawf.read()detectedchardet.detect(raw)[encoding]dfpd.read_csv(file_path,encodingdetected)print(f使用检测到的编码:{detected})returndf# 写入CSV确保Excel能正确打开defwrite_csv_excel_compatible(file_path,data,headers):写入Excel兼容的CSV带BOM头importcsv# 用utf-8-sig编码Excel打开不乱码withopen(file_path,w,encodingutf-8-sig,newline)asf:writercsv.DictWriter(f,fieldnamesheaders)writer.writeheader()writer.writerows(data)print(fCSV写入完成:{file_path})2.3 网页请求编码importrequests# 方法一让requests自动检测编码responserequests.get(https://example.com)response.encodingresponse.apparent_encoding# 用chardet检测的编码htmlresponse.text# 方法二手动指定编码responserequests.get(https://example.com)response.encodingutf-8# 或 gbk 等htmlresponse.text# 方法三从content手动解码最可靠responserequests.get(https://example.com)# 先尝试UTF-8try:htmlresponse.content.decode(utf-8)exceptUnicodeDecodeError:try:htmlresponse.content.decode(gbk)exceptUnicodeDecodeError:htmlresponse.content.decode(utf-8,errorsignore)# 从HTML的meta标签获取编码importre responserequests.get(https://example.com)contentresponse.content# 查找meta charsetmatchre.search(rbcharset[\]?([\w-]),content[:500])ifmatch:encodingmatch.group(1).decode(ascii)print(f网页声明的编码:{encoding})htmlcontent.decode(encoding)else:htmlcontent.decode(utf-8,errorsignore)2.4 JSON编码importjson data{name:张三,message:你好世界}# 错误中文变\uXXXXjson_strjson.dumps(data)print(json_str)# {name: \u5f20\u4e09, message: \u4f60\u597d\uff0c\u4e16\u754c\uff01}# 正确加ensure_asciiFalsejson_strjson.dumps(data,ensure_asciiFalse)print(json_str)# {name: 张三, message: 你好世界}![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2f3c24bfc3ad4cada49f30f4f5e793cc.png#pic_center)# 写入文件withopen(data.json,w,encodingutf-8)asf:json.dump(data,f,ensure_asciiFalse,indent2)# 读取文件withopen(data.json,r,encodingutf-8)asf:datajson.load(f)2.5 Excel编码importopenpyxl# openpyxl读写Excel一般不会有编码问题# 但如果数据来源有编码问题需要确保数据是str类型# 读取Excelwbopenpyxl.load_workbook(rD:\data\test.xlsx)wswb.activeforrowinws.iter_rows(values_onlyTrue):# openpyxl返回的值已经是正确的strnamestr(row[0])ifrow[0]elseprint(name)# 写入Excelwbopenpyxl.Workbook()wswb.active# 确保写入的是str类型data[张三,李四,王五]forrow_idx,nameinenumerate(data,1):ws.cell(rowrow_idx,column1,valuestr(name))wb.save(rD:\data\output.xlsx)# 用pandas处理importpandasaspd# 读取dfpd.read_excel(rD:\data\test.xlsx)# 写入df.to_excel(rD:\data\output.xlsx,indexFalse)2.6 控制台输出编码Windows的控制台默认用GBK编码Python输出UTF-8中文可能报错# 方法一在Python代码开头设置importsysimportio sys.stdoutio.TextIOWrapper(sys.stdout.buffer,encodingutf-8)sys.stderrio.TextIOWrapper(sys.stderr.buffer,encodingutf-8)print(中文输出测试)# 方法二设置环境变量在运行前设置importos os.environ[PYTHONIOENCODING]utf-8# 方法三在Windows终端切换编码# 运行命令: chcp 65001切换到UTF-8# 方法四用print的errors参数importsysifsys.platformwin32:sys.stdout.reconfigure(encodingutf-8,errorsreplace)2.7 数据库编码importsqlite3importmysql.connector# SQLite默认支持UTF-8connsqlite3.connect(rD:\data\rpa.db)cursorconn.cursor()cursor.execute(INSERT INTO products (name) VALUES (?),(张三,))conn.commit()# MySQL必须指定charsetconnmysql.connector.connect(hostlocalhost,databaserpa_data,userroot,passwordpassword,charsetutf8mb4# 必须设置不是utf8)2.8 编码统一检查器importchardetimportosdefcheck_file_encoding(file_path):检查文件编码withopen(file_path,rb)asf:rawf.read()resultchardet.detect(raw)return{file:file_path,encoding:result[encoding],confidence:result[confidence],size:len(raw),has_bom:raw[:3]b\xef\xbb\xbf}defbatch_check_encodings(directory):批量检查目录下所有文本文件的编码results[]forroot,dirs,filesinos.walk(directory):forfileinfiles:iffile.endswith((.txt,.csv,.json,.py,.md)):file_pathos.path.join(root,file)try:infocheck_file_encoding(file_path)results.append(info)# 标记有问题的文件ifinfo[encoding]notin(UTF-8,ascii)orinfo[confidence]0.9:print(f⚠️{file}:{info[encoding]}({info[confidence]:.1%}))ifinfo[has_bom]:print(f 有BOM头)exceptExceptionase:print(f检查失败{file}:{e})returnresults# 批量检查# results batch_check_encodings(rD:\data)# print(f\n共检查 {len(results)} 个文件)三、有什么坑坑1GBK和GB2312搞混# GBK是GB2312的超集GBK能解码的更多# chardet可能检测为GB2312但实际文件是GBK# 安全做法检测到GB2312时用GBKencodingchardet.detect(raw)[encoding]ifencodingGB2312:encodingGBK# GBK是GB2312的超集坑2半截中文字符TEMU店群矩阵自动化运营核价报活动UTF-8中文占3字节如果按字节截断可能截断到半个中文字符导致解码错误# 错误按字节截断raw中文测试.encode(utf-8)truncatedraw[:7]# 可能在中文字符中间截断# truncated.decode(utf-8) # UnicodeDecodeError# 正确用errorsignore忽略不完整的字符texttruncated.decode(utf-8,errorsignore)# 或者用errorsreplace替换texttruncated.decode(utf-8,errorsreplace)# 中文测?坑3Excel打开CSV乱码Excel默认用ANSIGBK编码打开CSVUTF-8的CSV打开后中文乱码。解决写入CSV时用utf-8-sig带BOMExcel能正确识别withopen(data.csv,w,encodingutf-8-sig,newline)asf:writercsv.writer(f)writer.writerow([姓名,年龄])![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2d3451920a474151b110e8072009ca47.png#pic_center)writer.writerow([张三,25])坑4文件路径含中文importos# Windows上中文路径可能有问题pathrD:\数据\采集结果\test.txt# 安全做法确保路径是unicodepathD:/数据/采集结果/test.txt# 用正斜杠# 或pathos.path.join(D:,数据,采集结果,test.txt)withopen(path,w,encodingutf-8)asf:f.write(测试)坑5编码转换丢字符从UTF-8转到GBK时GBK不支持的字符会丢失或变成问号# UTF-8有但GBK没有的字符会丢失text中文test# emoji在GBK中没有gbk_texttext.encode(gbk,errorsreplace)# 中文?testprint(gbk_text.decode(gbk))# 安全做法尽量统一用UTF-8避免编码转换总结编码问题的终极解决方案全局统一UTF-8——所有文件读写都加 encoding‘utf-8’CSV用utf-8-sig——Excel打开不乱码JSON加ensure_asciiFalse——中文不变\uXXXXMySQL用utf8mb4——不是utf8支持完整Unicode不确定编码用chardet——自动检测比猜靠谱避免编码转换——能统一用UTF-8就不要转来转去Windows控制台设PYTHONIOENCODING——防止输出乱码