使用Python3.6.1,请求2.13.0,我得到了被请求的URL的奇怪编码。我有一个在查询字符串中包含中文字符的URL,例如huà 話 用,它应该%-编码为hu%C3%A0%20%E8%A9%B1%20%E7%94%A8甚至hu%C3%A0+%E8%A9%B1+%E7%94%A8,但出于某种原因,它是%-编码为hu%C3%83%C2%A0%20%C3%A8%C2%A9%C2%B1%20%C3%A7%C2%94%C2%A8。这是不对的。我一直在使用http://r12a.github.io/apps/conversion/页来帮助我处理编码。我还使用了JavaScriptencodeURI和PHPurlencode并且没有得到任何接近我所看到的请求库所做的事情。我是不是做错了什么,以至于编码离得太远了?更新:我查看了Mojibake编码并进一步深入了请求库,发现了问题所在,但我仍然不确定如何解决它。我正在对一个内部服务器进行调用,使用一个简单的.get(url)调用。调用转到服务器并获得重定向响应。重定向页面的标题中有一个meta charset="UTF-8",其中列出的URL是正确的。离开服务器的location头是正常的;它被编码为UTF-8,Content-Type头上有一个charset=UTF-8头。但是,当我在Python中调试重定向响应时,我注意到响应对象上的头不正确,它似乎没有被正确解码。headers属性包含在location:huÃ\xa0 話 ç\x94中。如上所述,应解码为:huà 話 用。所以,那个奇怪的URL查询字符串get的%被请求编码,然后设置回服务器,然后服务器拒绝那个URL(显然)。我能做些什么来防止请求把事情搞砸吗?或者让它正确解码location头?网页浏览器似乎没有这个问题。 最佳答案 你有一个Mojibake编码。编码的字节是UTF-8字节的拉丁语-1解释的字节:>>> from urllib.parse import quote>>> text = 'huà 話 用'>>> quote(text)'hu%C3%A0%20%E8%A9%B1%20%E7%94%A8'>>> quote(text.encode('utf8').decode('latin1'))'hu%C3%83%C2%A0%20%C3%A8%C2%A9%C2%B1%20%C3%A7%C2%94%C2%A8'您可以通过再次手动编码到拉丁语-1,然后从UTF-8解码来反转该过程:>>> unquote('hu%C3%83%C2%A0%20%C3%A8%C2%A9%C2%B1%20%C3%A7%C2%94%C2%A8').encode('latin1').decode('utf8')'huà 話 用'或者,您可以使用 >自动修复错误的编码(通常会做得更好),尤其是当Windows碎片整理程序涉及到子查询时):>>> from ftfy import fix_text>>> fix_text(unquote('hu%C3%83%C2%A0%20%C3%A8%C2%A9%C2%B1%20%C3%A7%C2%94%C2%A8'))'huà 話 用'你说的是关于网址来源的:离开服务器的位置头是正常的;它被编码为UTF-8这就是你的问题,就在那里。HTTP头始终编码为拉丁语-1(*)。服务器必须将位置头设置为完全百分比编码的URL,以便将所有UTF-8字节表示为ftfy转义序列。这些只是ASCII字符,完全保存在拉丁-1上下文中。如果您的服务器以未转义的UTF-8字节的形式发送头,那么HTTP客户端(包括ftfy)会将其解码为拉丁-1,而不是导致您观察到的Mojibake问题。并且由于URL包含无效的URL字符,%HH将Mojibake结果转义为百分比编码版本。(*)实际上,requests头应该是一个requests library头,它始终是ASCII(7位)干净的数据,但是由于其他一些HTTP头允许“描述性”文本,因此拉丁语-1(ISO-8859-1)是头数据的默认编码。请参阅Location as per RFC2396,在解码任何报头中的非ASCII数据时,最终解码absoluteURI报头的TEXT rule in section 2.2 of the HTTP/1.1 RFC遵循此RFC。只有按照http.client module包装才能提供非拉丁-1数据,但这不适用于requests标题。关于python - Python请求奇怪的URL%-编码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43188661/
10-12 18:18