跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Python 3 中如何解决字典对字符串进行转义
未分類
11 4 月 2020

Python 3 中如何解决字典对字符串进行转义

Python 3 中如何解决字典对字符串进行转义

資深大佬 : euzen 65

str = “源代码”
bytes = str.encode(‘utf-8’)
str2 = bytes.decode(‘iso-8859-1’)
dict = {“key”: str2}
print(bytes)
print(str2)
print(dict)

运行结果:
b’xe6xbax90xe4xbbxa3xe7xa0x81′
源代码
{‘key’: ‘æºx90代çxa0x81’}

赋值给字典后,会对小于xa1 的字节进行转义,当使用 request.post 进行文件上传时,files 参数中涉及中文文件名就无法正确提交,有什么办法可以解决?

大佬有話說 (38)

  • 資深大佬 : InkStone

    这跟字典没什么关系吧。单纯是__repr__和__str__两个模式的输出不一样。

    你这个操作是什么意思?为什么要用 utf-8 编码,用 iso88591 解码?编码错误,传得上去才见鬼了吧

  • 資深大佬 : marquina

    实在没看懂这是什么操作……iso-8859-1 又不包含中文

  • 資深大佬 : zdnyp

    3.6 str2 和 dict[‘key’]的结果是一样的

    编码转的是不是有点没必要?

  • 主 資深大佬 : euzen

    @InkStone 服务器就是接受 iso-8859-1 编码,没有服务器方面的代码,不知道是怎么回事。也是试也好久解决这个中文的问题。

  • 主 資深大佬 : euzen

    @marquina 将 ‘源代码’提交到服务器是出错的,必须提交’xe6xbax90xe4xbbxa3xe7xa0x81′ 才可以。

  • 主 資深大佬 : euzen

    @zdnyp 对 python 还是新接触,既然 3.6 结果是一样,那么 3.7 是不是有什么参数,开关可以做到输出一样的结果?

  • 主 資深大佬 : euzen

    重点不是编码,是为什么赋值给字典后,字典会进行转义。

  • 資深大佬 : ungrown

    编解码不一致真的是迷
    你哪怕统一转换成 base64 也不这样靠谱

  • 資深大佬 : marquina

    @euzen 服务器只接受 iso-8859-1 编码就代表服务器不接受中文……这个时候要想给服务器中文,唯一的办法不就是让服务器支持 utf-8 等编码吗……

  • 資深大佬 : jyyx

    看下__repr__和 __str__的区别
    你把发出来的代码最后一行改成 print(dict[“key”])

  • 資深大佬 : Schalkiii

    代码里面不要写中文啥事没有…

  • 主 資深大佬 : euzen

    @marquina 我提交 iso-8859-1 的值上去,服务器会转换出中文,并非服务器不支持 utf-8,而且无法控制服务器行为。

  • 資深大佬 : Akikiki

    为什么要用关键字做变量

  • 主 資深大佬 : euzen

    @jyyx 噢,得到了相同的结果。也大概了解了一下__repr__和__str__。第一个解答也是切中要点的。

    但更让我迷茫了,看来是搞错了方向,要继续研究解决方案。

  • 資深大佬 : imn1

    不是,你现在上传有问题吗?什么问题?
    你纠结转义干嘛?x80~xa0 是不可视字符,当然转义啦

  • 資深大佬 : imn1

    你要上传的格式是什么?
    字典本身是不能上传的,字符串?那不就是 json 么? dict2json,根本不需要理会编码,中文都变成uxxxx 格式了

  • 資深大佬 : lc1450

    我猜你需要这个

    “`
    >>> from urllib.parse import quote
    >>> quote(“哈哈”)
    ‘%E5%93%88%E5%93%88’
    >>> quote(“哈哈”,encoding=’gbk’)
    ‘%B9%FE%B9%FE’
    “`

  • 主 資深大佬 : euzen

    @imn1 上传文件,使用 request.post,里面有个参数是 files,传一个字典进去即可,字典有三项,第一是文件名,第二是字节流,第三个是协议格式。如果我文件名是全英文的话没问题,中文则上传成功,但服务器那边解析不出中文文件名,最后结果出错了。

  • 主 資深大佬 : euzen

    @lc1450 这种方案已经试过来,服务器上是原样出来的,比如 哈哈.txt ,按这样解码,提交上去后服务器显示 %E5%93%88%E5%93%88.txt ,并不是我想要的结果。

  • 資深大佬 : also24

    咦,昨天群里有个人在问这个,我直接复制下我的回答:

    「 暴走的熊猫: python2 用 requests 库上传文件时,如果文件名是中文,上传失败,度娘一圈给的原因是中文文件名被进行 RFC 2231 编码了,导致找不到文件,给的解决方法被都是改源码,大佬们有其他方法么? 」
    – – – – – – – – – – – – – – –
    翻了一下,这个似乎是 urllib3 的锅
    https://github.com/psf/requests/issues/4652
    https://github.com/urllib3/urllib3/issues/303

    而 urllib3 似乎已经在 1.25 版本里修好了这个问题
    https://github.com/urllib3/urllib3/pull/1492
    https://github.com/urllib3/urllib3/blob/master/CHANGES.rst#125-2019-04-22

    你要不要看下你的 pip 或者 venv 里的 urllib3 的版本号

  • 資深大佬 : xuboying

    æºä»£ç 
    {‘key’: ‘æºx90代çxa0x81’}
    这两个内容有啥区别。。。

    这是你的 terminal 渲染的结果,如果你的 terminal 的 locale,( windows 下是 chcp 值) 不同,会用其他的字体渲染出其他的结果,就好比一个苹果放在中国会写成苹果,放在美国会写成 apple,本质是完全一样的东西。

    要担心的是 utf8 到 iso8859 的互转会不会丢失信息,毕竟你的服务器要按照 8865 的结果转回去。不知道是不是可逆的

  • 資深大佬 : also24

    刚睡醒,仔细看了下应该不是同一个问题,我再看看主到底想干啥…

  • 資深大佬 : also24

    认真的看了一下,主你这个问题没有描述清楚哈:

    > 服务器就是接受 iso-8859-1 编码
    这个是根据什么判定的?怎么测试出来的?

    > 必须提交’xe6xbax90xe4xbbxa3xe7xa0x81′ 才可以
    是说这样提交就可以正常使用?这个是 utf-8,不是 iso-8859-1 啊,和上一条的结论似乎不一样?

    > 使用 request.post
    指的是 requests.post 嘛?(少了 s )
    如果是的话,我现在怎么觉得和我一开始认为的是同一个问题了呢……
    如果是这样的话,那还是看一下 urllib3 的版本号

    BTW:
    赞同 @xuboying 关于最开始那几种展示无区别的看法。

    BBTW:
    我感觉主还没有把整个问题的完整情况搞清楚。
    建议使用抓包软件抓一下 requests 发出的原始请求,确认编码情况。

  • 資深大佬 : zappos

    也就是说 requests 库不会对 multipart 格式的中文自动编码是吧。我忘了 multipart 是怎么搞得了,你可以随便传个文件看一看。

    还有就是不要用不同的编码 encode 和 decode。

  • 資深大佬 : CRVV

    显然是 XY problem,还没把 Y 问题说清楚

    原本的问题是服务器不认 python 传过去的汉字,然后主拿 encode decode 和 iso-8859-1 折腾了一下就成功了,以为是服务器只支持 iso-8859-1。
    但实际上显然不是这么回事,如果服务器只支持 iso-8859-1,那就不可能成功地把汉字传上去。
    但是主又没说到底是怎么把字符串传给服务器的,如果是下面这样,说明服务器不支持 u4e2d 这种编码 unicode 的方法。json.dumps 有一些带默认值的参数,改一改可能服务器就支持了。

    >>> json.dumps(‘中’.encode(‘utf-8’).decode(‘iso-8859-1’))
    ‘”\u00e4\u00b8\u00ad”‘
    >>> json.dumps(‘中’)
    ‘”\u4e2d”‘

    至于后面的文件读不出来
    ‘源代码’ 这个字符串用 utf-8 编码过后的结果,再用 iso-8859-1 reinterpret 出来,就不是原来的字符串了,新的字符串是 ‘æºx90代çxa0x81’,如果你要读的文件是 ‘源代码’,那当然读不到

    .encode(‘utf-8’).decode(‘iso-8859-1’) 是相当于 float x = 3.14159; int* y = (int*)&x; 这样的操作,正常情况下不会用到的。

  • 主 資深大佬 : euzen

    @also24 urllib3 1.23.2
    我觉得也是你说的这个问题。

  • 主 資深大佬 : euzen

    @also24 自己另外搭了个测试页面来验证,有中文名字的话,服务器端接收完全是空的。

  • 主 資深大佬 : euzen

    @xuboying 是的,确认跟这个没关系,是我搞错方向了。

  • 主 資深大佬 : euzen

    @CRVV 的确是开始没搞清楚,跟编码没关系。

  • 資深大佬 : also24

    @euzen #27
    那和 urllib3 这个有关的可能性就非常大了……

    可以直接抓包把原始的请求内容拿出来看一下,或者在服务端打印一下所有字段的信息。

    懒得追查的话也可以先把 urllib3 升级到 1.25 版本以上看看问题会不会自动消失。

    你这个问题真的是搞了个超大的 X-Y Problem 出来……

  • 主 資深大佬 : euzen

    @also24 升级到 1.25.7,可以在测试服务器上看到文件名有数据了,虽然编码还是不对,但距离解决已不远,谢谢你的解答。前期纠结编码,主要是服务器不能管理,无法验证。

  • 資深大佬 : also24

    @euzen #31

    那就用我一直建议的抓包的方式,你 requests 配置一下 Proxies,然后用 Charles 之类的工具看一下发出去的原始请求的具体格式,避免一直黑箱状态下摸瞎改代码。

    https://2.python-requests.org/en/master/user/advanced/#proxies

  • 資深大佬 : luoleng

    想要啥效果?{‘key’: b’xe6xbax90xe4xbbxa3xe7xa0x81′}还是{‘key’: ‘xe6xbax90xe4xbbxa3xe7xa0x81’}

  • 主 資深大佬 : euzen

    @luoleng 原方向是需要后者的结果,但现在经 @also24 指点,发现跟字典无关,是 urllib3 低版本的问题。同时我关于字典会转义的指控也是错的,并没有转义,只是__repr__和__str__的区别。

  • 主 資深大佬 : euzen

    @also24 真是长见识了,requests 还可以使用 proxies,明天配合 burp 尝试一下。

  • 資深大佬 : also24

    @euzen #35
    哈哈哈哈,再多嘴两句哈,我觉得你查找问题的思路需要改进一下。

    不太建议上来就靠着直觉猜,应该先尽可能收集能收集到的信息(日志,原始请求等)。

    先搞清楚问题的全貌,才能对症下药,不然就很容易搞出这种 X-Y Problem,白费大量精力。

  • 資深大佬 : yhyh

    你这个问题 感觉有固定的方案可以解决,我奇葩的是 字典转 json, 而字典的值 有双引号
    哭了

  • 主 資深大佬 : euzen

    @CRVV 关于编码的问题,摸索了一天,再细读你的回复,利益不少。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具