2012-02-17 22 views
5

Estoy tratando de usar la gema nokogiri para extraer todas las direcciones URL en la página, así como su texto de enlace y almacenar el texto del enlace y la URL en un hash.¿Obtener enlace y texto href de html doc con Nokogiri & Ruby?

<html> 
    <body> 
     <a href=#foo>Foo</a> 
     <a href=#bar>Bar </a> 
    </body> 
</html> 

me gustaría volver

{"Foo" => "#foo", "Bar" => "#bar"} 

Respuesta

14

Aquí hay una sola línea:

Hash[doc.xpath('//a[@href]').map {|link| [link.text.strip, link["href"]]}] 

#=> {"Foo"=>"#foo", "Bar"=>"#bar"} 

Dividir un poco que posiblemente sea más legible:

h = {} 
doc.xpath('//a[@href]').each do |link| 
    h[link.text.strip] = link['href'] 
end 
puts h 

#=> {"Foo"=>"#foo", "Bar"=>"#bar"} 
+0

Gracias, funcionó a la perfección. – sunnyrjuneja

+0

Puede reemplazar 'link.attributes ['href']. Value' con solo [' link ['href'] '] (http://nokogiri.org/Nokogiri/XML/Node.html#method-i-5B -5D). – Phrogz

+0

@Phrogz ¡Gracias! Actualizado. –

2

Otro manera:

h = doc.css('a[href]').each_with_object({}) { |n, h| h[n.text.strip] = n['href'] } 
# yields {"Foo"=>"#foo", "Bar"=>"#bar"} 

Y si te preocupa que pueda tener el mismo enlace de texto para diferentes cosas, entonces recoja el href s en matrices:

h = doc.css('a[href]').each_with_object(Hash.new { |h,k| h[k] = [ ]}) { |n, h| h[n.text.strip] << n['href'] } 
# yields {"Foo"=>["#foo"], "Bar"=>["#bar"]} 
+0

El problema con la etiqueta 'a' es que se puede usar para enlaces y no enlaces como anclas con nombre. Debes verificar la presencia del atributo 'href'. –

+0

@Mark: Creo que cambié a 'a [href]' mientras comentabas por ese motivo. –

+0

Gracias, funcionó a la perfección. – sunnyrjuneja

Cuestiones relacionadas