Python中如何将十六进制编码的字符串转换为汉字?

限:py3 环境( py2 和 3 对于编码的处理是不一样的,很多教程根本不告诉你应用于哪个版本,害得我走了几个小时弯路!)
用 cmd 运行。
-----------------------------------------

爬虫爬到了一串\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f 数据,str 类型,这应该是 16 进制编码的汉字(嗯……应该是,我对编码一窍不通)
现在我想把它转成中文,方便和别的参数拼接成一串完整 URL 让 requests 访问。

在 B 乎找了个主意
https://www.zhihu.com/question/26921730

于是我把代码改成这样
data = (’\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f’).encode(‘UTF-8’).decode(‘unicode_escape’)
print (data)

cmd 里运行后变成大乱码
湖州新城建

我怀疑是编码不对,然而我对编码一窍不通,于是卡住了。

求怎么改才能让它输出中文?
Python中如何将十六进制编码的字符串转换为汉字?


18 回复

直接 decode 不行吗


# 十六进制编码字符串转汉字示例
hex_str = "e4b8ade59bbd"  # "中国"的UTF-8十六进制编码

# 方法1:使用bytes.fromhex()和decode()
def hex_to_chinese_1(hex_str):
    try:
        # 将十六进制字符串转换为bytes对象
        byte_data = bytes.fromhex(hex_str)
        # 解码为UTF-8字符串
        return byte_data.decode('utf-8')
    except (ValueError, UnicodeDecodeError) as e:
        return f"转换失败: {e}"

# 方法2:使用binascii模块(处理异常情况更灵活)
import binascii

def hex_to_chinese_2(hex_str):
    try:
        # unhexlify将十六进制字符串转换为bytes
        byte_data = binascii.unhexlify(hex_str)
        return byte_data.decode('utf-8')
    except (binascii.Error, UnicodeDecodeError) as e:
        return f"转换失败: {e}"

# 测试
print("方法1结果:", hex_to_chinese_1(hex_str))  # 输出: 中国
print("方法2结果:", hex_to_chinese_2(hex_str))  # 输出: 中国

# 处理带0x前缀或空格的情况
def robust_hex_to_chinese(hex_str):
    # 移除0x前缀和空白字符
    cleaned = hex_str.strip().lower().replace('0x', '').replace(' ', '')
    # 验证是否为有效十六进制
    if not all(c in '0123456789abcdef' for c in cleaned):
        return "无效的十六进制字符串"
    
    # 确保长度为偶数(十六进制字节对)
    if len(cleaned) % 2 != 0:
        cleaned = '0' + cleaned  # 前补零
    
    try:
        return bytes.fromhex(cleaned).decode('utf-8')
    except Exception:
        return "解码失败,请检查编码格式"

# 测试各种格式
test_cases = [
    "e4b8ade59bbd",
    "0xe4b8ade59bbd",
    "E4 B8 AD E5 9B BD",
    "e4b8ad"  # 奇数长度测试
]

for test in test_cases:
    print(f"'{test}' -> {robust_hex_to_chinese(test)}")

核心就两步:先用bytes.fromhex()把十六进制字符串转成字节,再用.decode('utf-8')解码成汉字。记得处理下格式问题就行。

湖州新

应该可以的吧

“湖州新�” ??直接转就好


不行,直接 decode 会报 AttributeError: ‘str’ object has no attribute 'decode’
因为 str 是不能解码的。这是 py3 的特性,py2 就没这个错了。(这就是我为此浪费了几个小时的弯路)

cmd 里面乱码的话,是什么环境?



你好,方法很暴力很有效。

但是我看到文档里提到,b 后面必须跟随单双引号

“ Python 对 bytes 类型的数据用带 b 前缀的单引号或双引号表示”
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431664106267f12e9bef7ee14cf6a8776a479bdec9b9000


实际上,\xe6\xb9\x96\xe5\xb7 ……是一串可变数据,我给它命名为 productName 方便引用。但是 b 后面一跟随变量就报错。

print (b(productName).decode(‘utf-8’, errors=‘ignore’))

NameError: name ‘b’ is not defined

如文档所说,单双引号里面必须存放写死的了数据,不能写变量。
如果 b 前缀只认可单双引号的话,变量这种东西该如何解呢?

谢谢。我是萌新,不好意思。

‘\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f’.encode(‘latin_1’).decode(‘utf8’, ‘ignore’)

b’…‘表示后面是 bytes 类型的数据,b’\x00’和 bytes([0])等价

b(productName) 函数调用或者创建实例

可以这样:
# st = r’\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f’
bytes([int(i, 16) if i else None for i in st.split(r’\x’)][1:]).decode(‘utf-8’, errors=‘ignore’)
或者:
# st = r’\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f’
eval(“b’”+(st)+"’").decode(‘utf-8’, errors=‘ignore’)

想知道你爬下来是句字符串吗? 不一般都是 bytes 吗

是,因为 type()看过类型。告诉我是 str。而且后面涉及切割什么的,别的也不好使啊。

十分感谢。不过我太菜了,看了半个小时不是很懂。
在看懂的过程中,突然想了个方法:把\x 替换成%,传递给浏览器地址栏
productName.replace(’\x’,’%’)
让浏览器给我解码去了。然后就算勉强曲线救国了。

无论如何,十分感谢你的帮助!!!谢谢,谢谢!!

bytes.fromhex(str).decode(‘utf-8’, errors=‘ignore’),这样可以吧

额,应该是这样,bytes.fromhex(str.replace(’\x’,’’)).decode(‘utf-8’, errors=‘ignore’)

了解一下内置的 struct 库

>>> s=r’\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f\x8e\xe5\xbb\xba’
>>> eval(‘b"’+s+’"’).decode(‘utf-8’)
'湖州新城建’
狐吧吧友雷吼啊,网上找的方法,我也不太会 py,不知道这样行不行。

python3 的 str 类型内部存的是 unicode, str.encode 默认编码是 utf-8,’\xe6\xb9\x96’.encode()结果并不是 b’\xe6\xb9\x96’

说一下结论,个人认为比较好的方式,使用 latin-1 或 charmap 编码器编码到相同字节的 bytes:
text = '\xe6\xb9\x96\xe5\xb7\x9e\xe6\x96\xb0\xe5\x9f\x8e\xe5\xbb\xba’
print(text.encode(‘latin-1’).decode(‘utf-8’))

或者手动映射:
print(bytes(map(ord, text)).decode(‘utf-8’))

回到顶部