2012-02-17 8 views
5

Próbuję użyć klejnotu nokogiri, aby wyodrębnić wszystkie adresy URL na stronie, a także ich tekst linku i zapisać tekst linku i URL w haszyszu.Uzyskaj link i tekst z html doc z Nokogiri i Ruby?

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

Chciałbym wrócić

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

Odpowiedz

14

Oto jeden-liner:

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

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

Dzielenie się trochę się zapewne bardziej czytelny:

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

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

Dzięki, pracował idealnie. – sunnyrjuneja

+0

Możesz zastąpić 'link.attributes ['href']. Value' za pomocą [' link ['href'] '] (http://nokogiri.org/Nokogiri/XML/Node.html#method-i-5B -5D). – Phrogz

+0

@Phrogz Dzięki! Zaktualizowano. –

2

Innym sposób:

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

A jeśli martwisz się, że może mieć taki sam łączenie tekstu do różnych rzeczy, potem zbierać href sw tablic:

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

Problem z tagiem 'a' polega na tym, że może on być użyty dla linków i nie-linków, takich jak nazwane kotwice. Musisz sprawdzić obecność atrybutu 'href'. –

+0

@ Mark: Myślę, że zmieniłem na 'a [href]' podczas komentowania właśnie z tego powodu. –

+0

Dzięki, działało idealnie. – sunnyrjuneja