2009-07-30 37 views
7

Tôi có một ứng dụng Sinatra (http://analyzethis.espace-technologies.com) nào sau đâyLàm thế nào để chuyển đổi một phản ứng Net :: HTTP thành một mã hóa nhất định trong Ruby 1.9.1?

  1. Lấy một trang HTML (thông qua net/http)
  2. Tạo một tài liệu Nokogiri từ response.body
  3. Trích xuất một số thông tin và gửi nó trở lại trong phản ứng. Câu trả lời phải được mã hóa UTF-8

Vì vậy, tôi đã gặp sự cố khi đọc các trang web sử dụng mã hóa windows-1256 như www.filfan.com hoặc www.masrawy.com.

Vấn đề là kết quả của việc chuyển đổi mã hóa không chính xác mặc dù không có lỗi nào được ném.

Các net/http response.body.encoding cho ASCII-8 bit mà không thể được chuyển đổi sang UTF-8

Nếu tôi làm Nokogiri :: HTML (response.body) và sử dụng bộ chọn css để có được một số nội dung từ trang - ví dụ: nội dung của thẻ tiêu đề - Tôi nhận được một chuỗi khi tôi gọi string.encoding trả về WINDOWS-1256. Tôi sử dụng string.encode ("utf-8") và gửi phản hồi bằng cách sử dụng nhưng một lần nữa phản hồi là không chính xác.

Bất kỳ đề xuất hoặc ý tưởng nào về những gì sai trong cách tiếp cận của tôi?

Trả lời

3

tôi thấy đoạn mã sau làm việc cho tôi bây giờ

def document 
    if @document.nil? && response 
    @document = if document_encoding 
        Nokogiri::HTML(response.body.force_encoding(document_encoding).encode('utf-8'),nil, 'utf-8') 
       else 
        Nokogiri::HTML(response.body) 
       end 
    end 
    @document 
end 

def document_encoding 
    return @document_encoding if @document_encoding 
    response.type_params.each_pair do |k,v| 
    @document_encoding = v.upcase if k =~ /charset/i 
    end 
    unless @document_encoding 
    #document.css("meta[http-equiv=Content-Type]").each do |n| 
    # attr = n.get_attribute("content") 
    # @document_encoding = attr.slice(/charset=[a-z1-9\-_]+/i).split("=")[1].upcase if attr 
    #end 
    @document_encoding = response.body =~ /<meta[^>]*HTTP-EQUIV=["']Content-Type["'][^>]*content=["'](.*)["']/i && $1 =~ /charset=(.+)/i && $1.upcase 
    end 
    @document_encoding 
end 
+0

Nó hoạt động tuyệt vời! –

20

Vì Net :: HTTP không xử lý mã hóa một cách chính xác. Xem http://bugs.ruby-lang.org/issues/2567

Bạn có thể phân tích response['content-type'] có chứa bộ ký tự thay vì phân tích cú pháp toàn bộ response.body.

Sau đó, sử dụng force_encoding() để đặt mã hóa đúng.

response.body.force_encoding("UTF-8") nếu trang web được phân phát bằng UTF-8.

+0

Mặc dù giải pháp này không hoạt động, vấn đề này chỉ xảy ra với tôi đối với một số trang web nhất định. Có lẽ khi Content-Type bao gồm 'application/json', thì nó sẽ mã hóa trong UTF-8 ...? Theo http://stackoverflow.com/questions/9254891/what-does-content-type-application-json-charset-utf-8-really-mean, application/json ngụ ý UTF-8. –

+1

Bước hợp lý tiếp theo sẽ là gọi .encode! ('UTF-8') trên chuỗi kết quả và sau đó thực hiện xử lý thực tế –

+0

@DmitryVyal Bạn đã lưu người bạn đời của mình – JustMichael

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