Незакрытые метки и нокогири - PullRequest
0 голосов
/ 08 декабря 2010

Мой тестовый HTML-файл находится здесь: http://pastebin.com/L88nYbQY

Как видите, есть несколько закрытых входных тегов, а также некоторые самозакрывающиеся.

Это приводит к тому, что следующий код возвращает все, начиная с открывающего #qcbody div до конца файла, игнорируя закрывающий тег div.

require 'nokogiri'

f = File.open('t.html', 'r')
@doc = Nokogiri::XML(f)
@doc.at_css('#qcbody').to_html

Я уверен, что люди обошли эту проблему разными способами. Как бы вы это сделали?

Ответы [ 2 ]

2 голосов
/ 09 декабря 2010

Попробуйте:

require 'open-uri'
require 'nokogiri'

@doc = Nokogiri::HTML(File.open('t.html', 'r'))
@doc.at_css('#qcbody').to_html

В IRB:

>> @doc.at_css('#qcbody').to_html
=> "<div id="qcbody">         \r\n    <form method="post" name="form" id="form" action="#">\r\n      <input type="hidden" name="Search Engine" id="Search Engine"><input type="hidden" name="Keyword" id="Keyword"><input type="button" onclick="javascript:validate()" name="sendsubmit" id="sendsubmit" class="submit">\n</form>\r\n    <div class="clear"></div>\r\n  </div>"

Разница между использованием Nokogiri::XML и Nokogiri::HTML заключается в снисхождении при разборе документа. XML требуется для проверки и правильности. Некоторые парсеры XML отклоняют XML-файл, который не соответствует стандарту. Nokogiri позволяет нам установить, насколько это придирчиво. (А в случае XML вы можете посмотреть на массив errors после анализа, чтобы увидеть, есть ли проблема.)

Для HTML Nokogiri ослабляет синтаксический анализатор, так что есть больше шансов работать с реальным HTML. Я видел, как он справляется с какой-то действительно уродливой разметкой и продолжает работать, когда меньшие парсеры подрывают свой обед. Если вы посмотрите на Nokogiri::HTML.parse, он определит options = XML::ParseOptions::DEFAULT_HTML, которые являются расслабленными настройками. Вы можете переопределить это, если хотите убедиться, что HTML соответствует.

1 голос
/ 08 декабря 2010
@doc = Nokogiri::HTML.parse(f)
@doc.at('#qcbody').to_html
...