我正在编写一个Python脚本来获取韩语词汇发音。我准备好了一个URL,当我在Safari中打开URL时,它会从服务器中检索预期的JSON。
当我使用requests
获取JSON时,调用失败并且未找到任何结果。
使用Charles,我可以看到,在将URL粘贴到Safari并点击回车后,带有原始查询的URL(韩语单词)是URL编码的。例如,URL字符串中的소instance实例在其出路时变为%EC%86%8C%EC%8B%9D
。
但是,当我使用requests
发出相同的请求时,该字词会被编码为%E1%84%89%E1%85%A9%E1%84%89%E1%85%B5%E1%86%A8
。两种编码都可以解码回原始单词소식(使用网络应用程序确认)。前一种编码是服务器接受的,后者不是。
为什么我会从requests
获得不同的编码?
修改
查询字符串以소식
的形式进入脚本 query = sys.argv[1]
sys.stderr.write(query)
- > 소식
将查询插入URL字符串会在打印时产生... json / word /소식....
通过查尔斯现在看起来像/json/word/%E1%84%89%E1%85%A9%E1%84%89%E1%85%B5%E1%86%A8/
。一切都是默认的,没有指定的编码。
答案 0 :(得分:3)
这些都是"相同"的有效网址编码。输入文字:
>>> from urllib.parse import unquote
>>> ulong = unquote('%E1%84%89%E1%85%A9%E1%84%89%E1%85%B5%E1%86%A8')
>>> ushort = unquote('%EC%86%8C%EC%8B%9D')
>>> ulong
'소식'
>>> ushort
'소식'
字符串实际上并不相同,但它们在unicode中有不同的形式:
>>> from unicodedata import name
>>> [name(x) for x in ulong]
['HANGUL CHOSEONG SIOS',
'HANGUL JUNGSEONG O',
'HANGUL CHOSEONG SIOS',
'HANGUL JUNGSEONG I',
'HANGUL JONGSEONG KIYEOK']
>>> [name(x) for x in ushort]
['HANGUL SYLLABLE SO', 'HANGUL SYLLABLE SIG']
我不知道任何韩语,但看起来长字符串由组合字符组成(你也可以看到类似的拉丁字符和重音字符)。如果我执行规范分解和表单的组合,我会得到平等:
>>> from unicodedata import normalize
>>> normalize('NFC', ulong) == ushort
True
所以,你要么使用不同的输入文本,要么看起来一样(甚至repr
还不足以看到差异,你必须检查代码点)或者你正在使用的方法之一 - 可能是浏览器 - 正在执行规范化/转换。
由于文本的简短形式适用于服务器,我建议您将脚本的输入规范化为NFC格式。