Нокогири душит документ с символом юникода (я думаю) в атрибуте title - PullRequest
0 голосов
/ 27 сентября 2011

У меня есть документ, похожий на этот ( обратите внимание на заголовок ):

<!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)

Результат от Нокогири таков:

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ã" заставляет нокогири просто задохнуться и подумать, что документ окончен. Как видите, #content div вообще не включено.

Кто-нибудь знает, как справиться с этой ситуацией?

Это убивает меня ... Спасибо !!

Edit: После дальнейших исследований я обнаружил, что фактическим персонажем, вызывающим удушье, является нулевой символ Unicode "\ u0000".

Прямо сейчас я думаю, что могу сделать что-то вроде этого:

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

1 Ответ

1 голос
/ 27 сентября 2011

Вы уверены, что символ после Sã является допустимым символом UTF-8?

Добавлено Существуют недопустимые последовательности символов UTF-8. Чтобы декодировать UTF-8 вручную, попробуйте этот декодер . Вы можете ввести входящий гекс, и он скажет вам, что означает каждый отдельный байт.

Хороший обзор UTF-8. UTF-8 кодовая таблица

Re: Удаление нулевого символа. Ваш код выглядит нормально, попробуйте! Но кроме того, я бы исследовал источник нуля во входящем потоке данных.

Кроме того, двоичный код 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
...