使用Nokogiri更改内容类型并不起作用

时间:2014-10-21 05:51:02

标签: html ruby nokogiri

我想更改" http-equiv"中的charset内容类型标记。因为我在代码的其他部分与Nokogiri合作,我也希望将它用于此处理步骤。

这是示例代码:

http_equiv = doc.at('meta[@http-equiv]')
    if !http_equiv.nil? && !http_equiv["http-equiv"].nil? && http_equiv["http-equiv"].downcase.eql?("content-type")
        http_equiv["content"] = "text/html; charset=utf-8"
    end
content = doc.to_html.encode(Encoding::UTF_8)

问题是输入内容总是与输出内容相同。 Nokogiri没有做任何事情。

根据答案,我创建了一个真实世界的例子,与生成的例子相比,它不会起作用。

require 'nokogiri'
require 'open-uri'

doc = require 'open-uri'
doc = Nokogiri::HTML(open("http://www.spiegel.de/politik/deutschland/hooligans-gegen-salafisten-demo-in-koeln-eskaliert-a-999401.html"))

content_type = doc.at('meta[@http-equiv="Content-Type"]')
content_type['content'] = 'text/html; charset=UTF-8'

puts doc.to_html

1 个答案:

答案 0 :(得分:1)

我会做这样的事情:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <head>
    <meta http-equiv="content-type" content="text/html">
  </head>
  <body>
  foo
  </body>
</html>
EOT

content_type = doc.at('meta[@http-equiv="content-type"]')
content_type['content'] = 'text/html; charset=UTF-8'
puts doc.to_html

运行输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=US-ASCII">
  </head>
  <body>
  foo
  </body>
</html>

您也可以

content_type['content'] << '; charset=UTF-8'

如果您只是追加现有价值。


  

它不会更改内容类型。

它会更改标记中的内容类型,但是由于您似乎不想更改内容类型标记,因此您需要在输出中更改文档本身的编码。一旦你这样做,Nokogiri也会更改元标记以匹配:

doc.to_html(encoding: 'UTF-8')

将告诉Nokogiri输出HTML,尝试从ISO-8859-1转换为UTF-8。但是不能保证会正确发生,因为存在一些不兼容性。

您的原始尝试使用:

content = doc.to_html.encode(Encoding::UTF_8)

将无法正常工作,因为特殊字符上会出现HTML编码。您必须在HTML编码之前更改字符编码,如果您使用to_html(encoding: 'UTF-8'),则会发生这种情况。