Nokogiri在标题属性中使用unicode char(我认为)对文档进行了扼流

时间:2011-09-27 16:55:23

标签: ruby encoding utf-8 character-encoding nokogiri

我有一个类似于此的文档(注意标题):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <title>Sã�ng Title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <div id="container">
      Some Text
    </div>
  </body>
</html>

当我使用此代码使用Nokogiri获取此文档时:

require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open(url).read)

Nokogiri的结果是:

ruby-1.9.2-p290 :060 > pp doc
#(Document:0x82e5ed2c {
  name = "document",
  children = [
    #(DTD:0x82e5e994 { name = "HTML" }),
    #(Element:0x82e5e0c0 {
      name = "html",
      attributes = [
        #(Attr:0x82e5e05c {
          name = "xmlns",
          value = "http://www.w3.org/1999/xhtml"
          }),
        #(Attr:0x82e5e048 {
          name = "xmlns:fb",
          value = "http://www.facebook.com/2008/fbml"
          })],
      children = [
        #(Element:0x82e5d8dc {
          name = "head",
          children = [
            #(Element:0x82e5d6d4 {
              name = "title",
              children = [ #(Text "Sã")]
              })]
          })]
      })]
  })

对我来说,看起来像“Sã”之后的角色会导致nokogiri只是窒息并认为文件已经结束。如您所见,#content div根本不包括在内。

任何人都知道如何处理这种情况?

这是在杀我......谢谢!!

编辑: 经过进一步的研究,我发现导致阻塞的实际字符是unicode null char“\ u0000”。

现在我想我可以做这样的事情:

page_content = open(url).read
# Remove null character
page_content.gsub!(/\u0000/, '')
Nokogiri::HTML(page_content)

1 个答案:

答案 0 :(得分:1)

你确定Sã之后的角色是有效的UTF-8角色吗?

已添加有非法的UTF-8字符序列。要手动解码UTF-8,请尝试此decoder。您可以输入传入的十六进制,它将告诉您每个字节的含义。

一个好的overview UTF-8。 UTF-8 code chart

Re:删除空字符。你的代码看起来不错,试一试!但另外,我会调查传入数据流中null的来源。

另外,原始帖子的二进制UTF-8实际上是未知字符符号 - 而不是原始数据流。以下是您帖子中的内容:

53 C3 A3 EF BF BD 6E 67

这是解码:

U+0053 LATIN CAPITAL LETTER S character
U+00E3 LATIN SMALL LETTER A WITH TILDE character (&#x00E3;)
U+FFFD REPLACEMENT CHARACTER character (&#xFFFD;)  # this is the char used when
                                                   # the orig is not understood.
U+006E LATIN SMALL LETTER N character
U+0067 LATIN SMALL LETTER G character