我正在http://hndroidapi.appspot.com/news/format/json/page/?appid=test从远程json中提取数据。我遇到的问题是这个API似乎正在构建JSON而没有正确处理UTF-8编码(如果我在这里错了,请纠正我)。例如,现在传递的部分结果是
{
"title":"IPad - please don€™t ding while you and I are asleep ",
"url":"http://modern-products.tumblr.com/post/25384729998/ipad-please-dont-ding-while-you-and-i-are-asleep",
"score":"10 points",
"user":"roee",
"comments":"18 comments",
"time":"1 hour ago",
"item_id":"4128497",
"description":"10 points by roee 1 hour ago | 18 comments"
}
注意don€™t
。而这并不是它窒息的唯一一种角色。鉴于我不控制API,我有什么办法可以将数据转换成干净的东西吗?
编辑:
以下是我如何提取JSON:
hn_url = "http://hndroidapi.appspot.com/news/format/json/page/?appid=test"
url = URI.parse(hn_url)
# Attempt to get the json
req = Net::HTTP::Get.new(hn_url)
req.add_field('User-Agent', 'Test')
res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
response = res.body
if response.nil?
puts "Bad response when fetching HN json"
return
end
# Attempt to parse the json
result = JSON.parse(response)
if result.nil?
puts "Error parsing HN json"
return
end
编辑2:
刚刚找到了API的GitHub页面。看起来这是一个突出的问题。仍然不确定我是否可以从我的角度做任何变通办法: https://github.com/glebpopov/Hacker-News-Droid-API/issues/4
答案 0 :(得分:4)
看起来您正在接收的JSON响应正文是以US-ASCII而不是UTF-8接收的,因为Net::HTTP
故意不强制编码。
1.9.3p194 :044 > puts res.body.encoding
US-ASCII
在Ruby 1.9.3中,如果你知道它应该是什么,你可以强制编码。试试这个:
response = res.body.force_encoding('UTF-8')
然后,JSON解析器应该按照您希望的方式处理UTF-8。
<强>参考强>
答案 1 :(得分:2)
使用force_encoding
似乎是最好的解决方案。
继凯文迪克森的答案之后,这里有一个奇怪的解释。
Net::HTTP
有点乱。
在1.9.3 :
http.request
对象调用Get
,则会获得US-ASCII。此方法不会为您执行压缩。http.get
,则会启用压缩功能。
你会得到US-ASCII,因为当Net::HTTP
创建缓冲区字符串来接收响应时,它是在解释器的默认源文件编码中创建的,它是US-ASCII。 (net/
源文件,顶部没有魔术编码注释,因此它们使用ruby的默认值。)
解压缩产生ASCII-8BIT,因为它在解压缩时用get
方法进行硬编码。
在2.0 上,好像你总是得到UTF-8,但这是因为这是默认的源文件编码。如果您通过-K
选项进行更改,则响应编码会相应更改。尝试将n
,e
,s
,u
传递给-K
。