【日常】如何处理“火星文”乱码

问题描述

爬虫中常常会遇到两种乱码,一种是https://blog.csdn.net/CY19980216/article/details/103116623中遇到的乱码,严格来说这不是乱码,这是字符编码后的结果,而且它根本不乱,只是我们看不懂而已,但是计算机是可以轻易读懂它是什么意思的。

第二种便是如下图所示的情况了👇

¡¾ÉϺ£ÕÐƸ£¬ÇóÖ°¡¿-Ç°³ÌÎÞÓÇ
▽奻漆桸ごㄛ⑴眦▼-ヶ最拸蚡

这些乱码是最近笔者在为老师爬取某就业信息网站时遇到的问题。其实之前也遇到过类似的乱码问题,一个字符用同一种编码方式编码解码当然会得到该字符本身,而这种乱码之所以会出现,其本质是字符使用了一种编码方式进行编码,然后却用另一种编码方式去解码,所以最终得到了一堆乱七八糟的串。

通常在爬虫中出现这种问题是因为许多网页的编码方式是ISO-8859-1,而计算机通用的编码方式是UTF-8与GBK,爬虫获取数据时获取到的是数据编码后的串,而最终我们看到的又是计算机为我们解码后的结果,所以会出现这些“火星文”,通常来说只需要把这几种常用的编码方式两两搭配去对这些“火星文”编码解码试试,看看哪一种会出正确的结果差不多就可以了。

这种方法相对来说比较凭据经验,做得多了有时候可以看出这些“火星文”大致是哪组编解码出的问题,至少上面两种情况的“火星文”显然是不同风格的“火星文”,自然也是不同组的编解码出的问题。凡事都有例外,这次我确实没能试出究竟是哪两种编码出的问题。

 

问题解决

为了方便以后快速找到哪两种编码方式,笔者编写了以下方法供参考👇

# -*- coding=UTF-8 -*-
import os

"""
	作者:囚生CY
	平台:CSDN
	时间:2019/11/22
	转载请注明原作者
	创作不易,仅供分享
"""

class Mycode():
	def __init__(self,
		pypath="E:/python",
		codes=None,
	):
		self.pypath = pypath.replace("\\","/")
		self.pypath = self.pypath[:-1] if self.pypath[-1]=="/" else self.pypath
		if codes: self.codes = codes									 # 用户指定编码列表则使用自定义编码方式列表
		else: 															 # 否则从python根目录下读取所有编码方式
			self.codes = []
			for filename in os.listdir("{}/lib/encodings".format(self.pypath)):
				code = filename.split(".")[0]
				try: a = "1".encode(code)
				except: continue
				self.codes.append(code)				
	
	def transform(self,string,log=False,logpath="C:/Users/lenovo/Desktop"):
		logpath = logpath.replace("\\","/")
		logpath = logpath[:-1] if logpath[-1]=="/" else logpath
		for x in self.codes:
			for y in self.codes:
				try: temp = string.encode(x).decode(y)
				except: continue
				result = "encode:{}\tdecode:{}\tresult:\t{}".format(x,y,temp)
				print(result)
				if log:
					 with open("{}/mycode_log.txt","a") as f: 
						 f.write("{}\n".format(result))

if __name__ == "__main__":
	mycode = Mycode()
	mycode.transform("¡¾ÉϺ£ÕÐƸ£¬ÇóÖ°¡¿-Ç°³ÌÎÞÓÇ")

注意到,python的根目录下的Lib文件夹中的encodings文件夹中存了一百多种编码方式的py文件,如笔者的python根目录在E:/python/,则该文件夹在E:/python/Lib/encodings/👇

这些文件的文件名恰为编码的名称,笔者试图遍历所有的“编码方式对”去找到正确的处理方式,上面代码运行结果如下👇

可以看到使用charmap编码,gb18030/gb2312/gbk解码即可使得这串“火星文”变成能够读懂的汉字。

当然这种“编码方式对”未必唯一,有人说一百多种编码方式对得有一万多种情况,这该怎么找呢?

笔者推荐视力好的直接翻了找,视力差的去配副好点的眼镜,如果瞎了的话就列个常用字符库(中英文都要有,但一般来说出现火星文都是中文的问题),多写点代码大致判断一下上图result后的字符串是正常字符串的概率是多少,做个预筛选,然后再摸索。

分享学习,共同进步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章