2011-05-23 7 views
14

Estoy recortando una página html con nokogiri y quiero quitar todos los atributos de estilo.
¿Cómo puedo lograr esto? (No estoy usando los carriles, así que no puedo utilizar es el método de higienización y yo no quiero usar la gema desinfectar porque yo quiero a la lista negra no retire lista blanca)Atributos de estilo de tira con nokogiri

html = open(url) 
doc = Nokogiri::HTML(html.read) 
doc.css('.post').each do |post| 
puts post.to_s 
end 

=> <p><span style="font-size: x-large">bla bla <a href="http://torrentfreak.com/netflix-is-killing-bittorrent-in-the-us-110427/">statistica</a> blabla</span></p> 

quiero que sea

=> <p><span>bla bla <a href="http://torrentfreak.com/netflix-is-killing-bittorrent-in-the-us-110427/">statistica</a> blabla</span></p> 

Respuesta

15
require 'nokogiri' 

html = '<p class="post"><span style="font-size: x-large">bla bla</span></p>' 
doc = Nokogiri::HTML(html) 
doc.xpath('//@style').remove 
puts doc.css('.post') 
#=> <p class="post"><span>bla bla</span></p> 

Editado para mostrar que sólo se puede llamar NodeSet#remove en lugar de tener que utilizar .each(&:remove).

Tenga en cuenta que si tiene un DocumentFragment en lugar de un documento, Nokogiri tiene a longstanding bug donde la búsqueda desde un fragmento no funciona como era de esperar. La solución consiste en utilizar:

doc.xpath('@style|.//@style').remove 
+0

wow. ¡eso es fácil! Lo amo. ¡Gracias! – keepitterron

+0

Use 'doc.xpath ('.//@stilo'). Remove' para eliminar todos los estilos en línea de todos los nodos, observe el' .' al principio como lo menciona @bricker a continuación. Encadena '.to_s' para obtener la cadena html resultante. –

+0

Corrección: No lo encadene pero use 'description.to_s' para obtener la cadena html resultante. Si no desea el 'DOCTYPE', debe usar el método' Nokogiri :: HTML.fragment' en su lugar, vea http://stackoverflow.com/questions/4723344/how-to-prevent-nokogiri-from-adding- doctype-tags –

3

Probé la respuesta de Phrogz, pero no pudo conseguir que funcione (que estaba usando un fragmento de documento, pero aunque habría pensado que debería funcionar de la misma?).

Al principio "//" no parecía estar controlando todos los nodos como era de esperar. Al final hice algo un poco sin aliento a más largo pero funcionó, por lo que aquí para el registro en caso de que alguien más tiene el mismo problema es mi solución (sucio aunque es):

doc = Nokogiri::HTML::Document.new 
body_dom = doc.fragment(my_html) 

# strip out any attributes we don't want 
body_dom.xpath('.//*[@align]|*[@align]').each do |tag| 
    tag.attributes["align"].remove 
end 

Saludos

Pete

+1

Esto también funcionaría probablemente: 'body_dom.xpath ('.//@class')' (fíjate en el punto extra al comienzo de xpath) – bricker

+0

Nokogiri y/o LibXML2 tienen [un error con XPath dentro de los fragmentos ] (https://github.com/sparklemotion/nokogiri/issues/572). La mejor solución actual para fragmentos es la que usted nota: en lugar de '// foo' debe usar' foo | .// foo'. – Phrogz

8

Esto funciona tanto con un documento y un fragmento de documento:

doc = Nokogiri::HTML::DocumentFragment.parse(...) 

o

doc = Nokogiri::HTML(...) 

Para eliminar todo el 'estilo' atributos, se puede hacer un

doc.css('*').remove_attr('style') 
Cuestiones relacionadas