【问题标题】:How to convert a Net::HTTP response to a certain encoding in Ruby 1.9.1?如何将 Net::HTTP 响应转换为 Ruby 1.9.1 中的某种编码?
【发布时间】:2010-11-15 11:50:16
【问题描述】:

我有一个执行以下操作的 Sinatra 应用程序 (http://analyzethis.espace-technologies.com)

  1. 检索 HTML 页面(通过 net/http)
  2. 从 response.body 创建一个 Nokogiri 文档
  3. 提取一些信息并在响应中发回。响应应采用 UTF-8 编码

所以我在尝试阅读使用 windows-1256 编码的网站(如 www.filfan.com 或 www.masrawy.com)时遇到了问题。

问题是编码转换的结果不正确,虽然没有报错。

net/http response.body.encoding 给出的 ASCII-8BIT 不能转换为 UTF-8

如果我执行 Nokogiri::HTML(response.body) 并使用 css 选择器从页面获取某些内容 - 例如标题标签的内容 - 我得到一个字符串,当我调用 string.encoding 返回视窗-1256。我使用 string.encode("utf-8") 并使用它发送响应,但响应再次不正确。

关于我的方法有什么问题有什么建议或想法吗?

【问题讨论】:

    标签: ruby http encoding sinatra ruby-1.9


    【解决方案1】:

    因为 Net::HTTP 不能正确处理编码。见http://bugs.ruby-lang.org/issues/2567

    您可以解析包含字符集的response['content-type'],而不是解析整个response.body

    然后使用force_encoding()设置正确的编码。

    response.body.force_encoding("UTF-8") 如果网站以 UTF-8 格式提供。

    【讨论】:

    • 虽然这个解决方案确实有效,但这个问题只发生在我的某些网站上。也许当 Content-Type 包含“application/json”时,它确实以 UTF-8 编码......?根据stackoverflow.com/questions/9254891/…,application/json 意味着 UTF-8。
    • 下一个合乎逻辑的步骤是在结果字符串上调用 .encode!('UTF-8') 然后进行实际处理
    • @DmitryVyal 你救了我的朋友
    【解决方案2】:

    我发现以下代码现在对我有用

    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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 2016-04-13
      相关资源
      最近更新 更多