2012-06-18 24 views
5

Tôi đang lấy dữ liệu từ json từ xa tại http://hndroidapi.appspot.com/news/format/json/page/?appid=test. Vấn đề tôi đang gặp phải là API này dường như đang xây dựng JSON mà không xử lý đúng mã hóa UTF-8 (đúng với tôi nếu tôi sai ở đây). Ví dụ: một phần của kết quả được thông qua ngay bây giờ làXử lý xấu UTF-8 từ json, trong ruby ​​

{ 
"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" 
} 

Lưu ý don€™t. Và đó không phải là loại nhân vật duy nhất mà nó đang bị nghẹt thở. Có bất kỳ điều gì tôi có thể làm để chuyển đổi dữ liệu thành dữ liệu gì đó sạch sẽ không, vì tôi không kiểm soát API?

Edit:

Sau đây là cách tôi kéo xuống 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 

Chỉnh sửa 2:

Chỉ cần tìm thấy trang GitHub của API. Có vẻ như đây là một vấn đề nổi bật. Vẫn không chắc chắn nếu có bất kỳ cách giải quyết mà tôi có thể làm lại từ cuối của tôi: https://github.com/glebpopov/Hacker-News-Droid-API/issues/4

+0

Có vẻ như nội dung phản hồi JSON bạn đang nhận có thể bao gồm các ký hiệu an toàn HTML. Tôi không thấy bất kỳ ký tự xấu nào trong nháy mắt, và tôi thấy rằng tiêu đề phản hồi 'Content-Type' được đặt thành' application/json; charset = utf-8', có vẻ chính xác. Làm thế nào bạn nhận được cơ thể phản ứng? Tôi sẽ thử kiểm tra phản hồi bằng công cụ trình duyệt như 'Dev HTTP Client' hoặc CURL và xem ứng dụng của bạn có khác biệt với phản hồi thực tế hay không. Nếu vậy, bạn có thể xử lý nó không chính xác trong mã của bạn. –

+0

Cảm ơn. Tôi đã thêm mã của mình vào bản chỉnh sửa. Tuy nhiên, vấn đề là chúng là các ký hiệu an toàn HTML. Tuy nhiên, nó không phải là một biểu tượng Euro và một biểu tượng 'tm'. Nó phải là một dấu nháy đơn. – hodgesmr

+0

Bạn có thể xem phản hồi chính xác trong bảng điều khiển bằng cách sử dụng 'đặt res.body'. Bạn có thấy các biểu tượng sôi nổi sau này thông qua đối tượng 'kết quả' không? –

Trả lời

4

Dường như cơ thể phản ứng JSON bạn đang nhận được nhận được trong US-ASCII thay vì UTF-8 vì Net::HTTP cố không mã hóa lực.

1.9.3p194 :044 > puts res.body.encoding 
US-ASCII 

Trong Ruby 1.9.3, bạn có thể buộc mã hóa nếu bạn biết nó được cho là gì. Hãy thử cách này:

response = res.body.force_encoding('UTF-8') 

Trình phân tích cú pháp JSON sẽ xử lý UTF-8 theo cách bạn muốn.

Tài liệu tham khảo

1

Sử dụng force_encoding có vẻ như giải pháp tốt nhất. Theo dõi câu trả lời của Kevin Dickerson, đây là giải thích về sự kỳ quặc.

Net::HTTP là loại lộn xộn.

On 1.9.3:

  • Nếu máy chủ sẽ gửi một phản ứng chunked, bạn sẽ luôn có được ASCII-8 bit. Điều này dường như được ưu tiên hơn các tình huống khác.
  • Nếu bạn gọi http.request với đối tượng Get, bạn sẽ nhận được US-ASCII. Phương pháp này không nén cho bạn.
  • Nếu bạn gọi http.get, tính năng nén được bật.
    • nều server hỗ trợ nén, bạn sẽ nhận được ASCII-8 bit
    • nếu máy chủ không gửi một cơ thể nén, bạn sẽ nhận được US-ASCII

bạn muốn nhận US-ASCII bởi vì khi Net::HTTP tạo chuỗi bộ đệm để nhận phản hồi, nó được tạo trong mã hóa tệp nguồn mặc định của trình thông dịch, là US-ASCII. (Các tệp nguồn net/, không có nhận xét mã hóa ở trên cùng, vì vậy chúng sử dụng giá trị mặc định của ruby.)

Giải nén tạo ASCII-8BIT vì nó được mã hóa để làm điều đó trong phương pháp get khi giải nén.

Trên 2.0, có vẻ như bạn luôn nhận được UTF-8, nhưng điều này là do đó là mã hóa tệp nguồn mặc định. Nếu bạn thay đổi thông qua tùy chọn -K, mã hóa phản hồi sẽ thay đổi tương ứng. Thử vượt qua n, e, s, u đến -K.

Các vấn đề liên quan