ruby-on-rails ruby web-scraping web-crawler nokogiri

ruby on rails - ¿Cómo elimino HTML entre dos comentarios HTML usando Nokogiri?



ruby-on-rails web-scraping (1)

Extraer contenido entre dos nodos no es algo normal que haríamos; Normalmente querríamos contenido dentro de un nodo particular. Los comentarios son nodos, solo son tipos especiales de nodos.

require ''nokogiri'' doc = Nokogiri::HTML(<<EOT) <body> <!-- begin content --> <div>some text</div> <div><p>Some more elements</p></div> <!-- end content --> </body> EOT

Al buscar un comentario que contenga el texto especificado, es posible encontrar un nodo inicial:

start_comment = doc.at("//comment()[contains(.,''begin content'')]") # => #<Nokogiri::XML::Comment:0x3fe94994268c " begin content ">

Una vez que se encuentra, se necesita un bucle que almacena el nodo actual, luego busca el siguiente hermano hasta que encuentra otro comentario:

content = Nokogiri::XML::NodeSet.new(doc) contained_node = start_comment.next_sibling loop do break if contained_node.comment? content << contained_node contained_node = contained_node.next_sibling end content.to_html # => "/n <div>some text</div>/n <div><p>Some more elements</p></div>/n"

Tengo algunas páginas HTML donde los contenidos que se extraerán están marcados con comentarios HTML como a continuación.

<html> ..... <!-- begin content --> <div>some text</div> <div><p>Some more elements</p></div> <!-- end content --> ... </html>

Estoy usando Nokogiri e intento extraer el HTML entre los contenidos <!-- begin content --> y <!-- end content --> .

Quiero extraer los elementos completos entre estos dos comentarios HTML:

<div>some text</div> <div><p>Some more elements</p></div>

Puedo obtener la versión de solo texto usando la devolución de llamada de estos personajes:

class TextExtractor < Nokogiri::XML::SAX::Document def initialize @interesting = false @text = "" @html = "" end def comment(string) case string.strip # strip leading and trailing whitespaces when /^begin content/ # match starting comment @interesting = true when /^end content/ @interesting = false # match closing comment end def characters(string) @text << string if @interesting end end

Obtengo la versión de solo texto con @text pero necesito el HTML completo almacenado en @html .