如何将 Net::HTTP 响应转换为 Ruby 1.9.1 中的某种编码?

发布于 2024-07-29 03:13:54 字数 670 浏览 3 评论 0原文

我有一个 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 时返回 WINDOWS-1256。 我使用 string.encode("utf-8") 并使用它发送响应,但响应再次不正确。

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

I have a Sinatra application (http://analyzethis.espace-technologies.com) that does the following

  1. Retrieve an HTML page (via net/http)
  2. Create a Nokogiri document from the response.body
  3. Extract some info and send it back in the response. The response should be UTF-8 encoded

So I came to the problem while trying to read sites that use windows-1256 encodings like www.filfan.com or www.masrawy.com.

The problem is the result of the encoding conversion is not correct though no errors are thrown.

The net/http response.body.encoding gives ASCII-8BIT which can not be converted to UTF-8

If I do Nokogiri::HTML(response.body) and use the css selectors to get certain content from the page - say the content of the title tag for example - I get a string which when i call string.encoding returns WINDOWS-1256. I use string.encode("utf-8") and send the response using that but again the response is not correct.

Any suggestions or ideas about what's wrong in my approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清秋悲枫 2024-08-05 03:13:54

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

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

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

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

Because Net::HTTP does not handle encoding correctly. See http://bugs.ruby-lang.org/issues/2567

You can parse response['content-type'] which contains charset instead of parsing whole response.body.

Then use force_encoding() to set right encoding.

response.body.force_encoding("UTF-8") if site is served in UTF-8.

听,心雨的声音 2024-08-05 03:13:54

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

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 

I found the following code working for me now

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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文