python3中字符编码的问题
记录瞬间
只要是在做开发的工作,几乎都会遇到编码的问题,恰巧最近遇到一些基本的py3编码问题,作以记述,以备不时之需。
1、十六进制与中文
第一种情况:\x开头的编码是十六进制字符,\x后面跟的字符即为十六进制的字符串。 存在 \ 转义 \\ 的情况下,处理方法如下
info = '\\xe8\\xa7\\xa3\\xe6\\x9e\\x84\\xe6\\x89\\xb9\\xe8\\xaf\\x84\\xe6\\x8e\\xa2\\xe7\\xa7\\x98'#字符串类型 out = bytes(info,'utf-8').decode('unicode_escape').encode('latin1').decode() print(out)
输出:
解构批评探秘
第二种情况:不存在转义的情况下,即字符串中只有 \
info = '\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'#字符串类型 info = info.encode('unicode_escape').decode('utf-8') out = bytes(info,'utf-8').decode('unicode_escape').encode('latin1').decode() print(out)
输出:
你好世界
第三种情况:解决url替换
from urllib import parse
info = '\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c' info = info.encode('unicode_escape').decode('utf-8').replace('\\x', '%') out = parse.unquote(info) print(out)
from urllib.parse import quote, unquote
ll={"query":"%E6%8A%80%E9%AB%98%E4%B8%80%E7%AD%B9"} out=json.loads(unquote(ll)) print(out)
from urllib.parse import unquote ll = {"AbsStr":"%\\/E\\/6\\/%\\/9\\/D\\/%\\/83%\\/E\\/5\\/%\\/8\\/A\\/%\\/9\\/B\\/%\\/E\\/7\\/%\\/9\\/A\\/%\\/84%\\/E\\/6\\/%\\/B\\/8\\/%\\/B\\/8\\/%\\/E\\/6\\/%\\/88%\\/8\\/F"} out = = json.loads(unquote(unquote(response_data.replace('\\\\/', '')))) print(out)
输出:
你好世界
"query": 技高一筹
'AbsStr': '权力的游戏'
第四种情况:直接是bytes类型
info = b'\xE6\x88\x91\xE6\x98\xAF\xE8\xAF\xB7\xE6\xB1\x82' info = info.decode('utf-8') print(info)
输出:
我是请求
2、URL的编码与解码
第一、编码文字
from urllib import parse print(parse.quote("你好"))
输出:
%E4%BD%A0%E5%A5%BD
第二、编码字典
from urllib import parse args = { 'wd': '你好', 'ie': '哈哈' } url = "http://www.baidu.com/s?{}".format(parse.urlencode(args)) print(url)
输出:
http://www.baidu.com/s?wd=%E4%BD%A0%E5%A5%BD&ie=%E5%93%88%E5%93%88
第三、解码
from urllib import parse print(parse.unquote("http://www.baidu.com/s?wd=%E4%BD%A0%E5%A5%BD&ie=%E5%93%88%E5%93%88"))
输出:
http://www.baidu.com/s?wd=你好&ie=哈哈
第四、解码字典
from urllib import parse params = { 'name': '张三', 'age': 18, 'greet': 'hello' } qs = parse.urlencode(params) print(qs) result = parse.parse_qs(qs) print(result)
输出:
name=%E5%BC%A0%E4%B8%89&age=18&greet=hello {'name': ['张三'], 'age': ['18'], 'greet': ['hello']}
第五、url的解析
from urllib import parse url = 'http://www.baidu.com/s?wd=python&username=abc#1' result = parse.urlparse(url) print('scheme:', result.scheme) print('netloc:', result.netloc) print('path:', result.path) print('params:', result.params) print('query:', result.query) print('fragment:', result.fragment)
输出:
scheme: http netloc: www.baidu.com path: /s params: query: wd=python&username=abc fragment: 1
第六、url提取查询参数
from urllib import parse url = 'http://www.baidu.com/s?wd=python&username=abc#1' def get_query(url): result = parse.urlparse(url) querys = parse.parse_qs(result.query) querys = {k: v[0] for k, v in querys.items()} return querys print(get_query(url))
输出:
{'wd': 'python', 'username': 'abc'}
3、unicode与中文
第一
s = '\\u9500\\u552e' print(json.loads(f'"{s}"')) print(s.encode('utf-8').decode("unicode_escape"))
输出:
销售
销售
第二
i = '\u751F\u5316\u5371\u673A' print(str(i))
输出:
生化危机
引用: https://blog.csdn.net/dzdzdzd12347/article/details/124648872
实战:如果返回的数据是一个json,里面的数据中存在某些value是需要解码的,如下代码
def decode_json(self, source, target): if type(source) == list: for data in source: if type(data) == dict: for key, value in data.items(): if type(value) == str and "\\x" in value: result = bytes(value, 'utf-8').decode('unicode_escape').encode('raw_unicode_escape').decode() print(result) if type(value) == list: self.decode_json(value, target) if type(value) == dict: self.decode_json(value, target) if type(data) == list: self.decode_json(data, target) elif type(source) == dict: for key, value in source.items(): if type(value) == str and "\\x" in value: result = bytes(value, 'utf-8').decode('unicode_escape').encode('raw_unicode_escape').decode() print(result) if type(value) == list: self.decode_json(value, target) if type(value) == dict: self.decode_json(value, target)
当然,我们也有更简便的方法进行解决,假设获取的数据中 response_data 是一个字符串,那么可以直接通过方法进行解决
get_str = bytes(response_data, 'utf-8').decode('unicode_escape').encode('raw_unicode_escape').decode() return_data = json.loads(get_str.replace('\\\\"', '\\"').replace('""', '"########"')) print(return_data)