Как Nokogiri обрабатывает закрытые теги HTML, такие как <br>? - PullRequest
5 голосов
/ 19 августа 2011

При разборе HTML-документа, как Nokogiri обрабатывает <br> теги? Предположим, у нас есть документ, который выглядит так:

<div>
   Hi <br>
   How are you? <br>
</div>

Знает ли Нокогири, что теги <br> являются чем-то особенным, а не просто обычными тегами XML, и игнорируют их при разборе канала? Я думаю, что Nokogiri настолько умен, но я хочу удостовериться, прежде чем принять этот проект, включающий в себя очистку сайта, написанного в формате HTML4. Вы знаете, что я имею в виду (How are you? не является содержимым первого <br>, как это было бы в XML).

Ответы [ 3 ]

4 голосов
/ 19 августа 2011

Вы должны проанализировать этот фрагмент с помощью анализатора HTML, поскольку очевидно, что это недопустимый XML.При использовании HTML-кода Nokogiri тогда ведет себя так, как вы ожидаете:

require 'nokogiri'

doc = Nokogiri::HTML(<<-EOS
<div>
   Hi <br>
   How are you? <br>
</div>
EOS
)

doc.xpath("//br").each{ |e| puts e }

printts

<br>
<br>

Механизация основана на Nokogiri для выполнения веб-скребков, поэтому это вполне уместнодля задания.

3 голосов
/ 19 августа 2011

Вот как Nokogiri ведет себя при разборе (искаженном) XML :

require 'nokogiri'
doc = Nokogiri::XML("<div>Hello<br>World</div>")
puts doc.root
#=> <div>Hello<br>World</br></div>

Вот как Nokogiri ведет себя при разборе HTML :

require 'nokogiri'
doc = Nokogiri::HTML("<div>Hello<br>World</div>")
puts doc.root
#=> <html><body><div>Hello<br>World</div></body></html>

p doc.at('div').text
#=> "HelloWorld"

Я предполагаю, что под «чем-то особенным» вы подразумеваете, что хотите, чтобы Нокогири воспринимал это как новую строку в исходном тексте. <br> является не чем-то особенным, и поэтому, соответственно, Нокогири не трактует это иначе, чем любой другой элемент.

Если вы хотите, чтобы это воспринималось как перевод строки, вы можете сделать это:

doc.css('br').each{ |br| br.replace("\n") }
p doc.at('div').text
#=> "Hello\nWorld"

Аналогично, если вы хотите вместо этого пробел:

doc.css('br').each{ |br| br.replace(" ") }
p doc.at('div').text
#=> "Hello World"
0 голосов
/ 19 августа 2011

Насколько я помню, после анализа HTML в прошлом году они будут рассматриваться как отдельные.

РЕДАКТИРОВАТЬ: мой плохой, у меня просто есть кто-то, чтобы отправить мне код и перепроверять его, мы закончили с чем-то, включая <br> отдельно.

...