web-dev-qa-db-fra.com

Obtenir la valeur de l'attribut dans Nokogiri pour extraire les URL de lien

J'ai un document qui ressemble à ceci:

<div id="block">
    <a href="http://google.com">link</a>
</div>

Nokogiri ne peut pas me donner la valeur de l'attribut href. Je voudrais stocker l'adresse dans une variable Ruby sous forme de chaîne.

27
Kreeki
html = <<HTML
  <div id="block">
    <a href="http://google.com">link</a>
  </div>
HTML
doc = Nokogiri::HTML(html)
doc.xpath('//div/a/@href')
#=> [#<Nokogiri::XML::Attr:0x80887798 name="href" value="http://google.com">]

Ou si vous voulez être plus précis sur la div:

>> doc.xpath('//div[@id="block"]/a/@href')
=> [#<Nokogiri::XML::Attr:0x80887798 name="href" value="http://google.com">]
>> doc.xpath('//div[@id="block"]/a/@href').first.value
=> "http://google.com"
46
Michael Kohl
doc = Nokogiri::HTML(open("[insert URL here]"))
href = doc.css('#block a')[0]["href"]

La variable href est affectée à la valeur de l'attribut "href" pour l'élément <a> dans l'élément portant l'ID 'block'. La ligne doc.css('#block a') renvoie un tableau d'éléments unique contenant les attributs de #block a. [0] cible cet élément unique, qui est un hachage contenant tous les noms et valeurs d'attributs. ["href"] cible la clé de "href" à l'intérieur de ce hachage et renvoie la valeur, qui est une chaîne contenant l'URL. 

26
seldomatt

Après avoir lutté avec cette question sous diverses formes, j'ai décidé d'écrire moi-même un tutoriel déguisé en réponse. Cela peut être utile aux autres.

Commençant par cet extrait:

require 'rubygems'
require 'nokogiri'

html = <<HTML
<div id="block1">
    <a href="http://google.com">link1</a>
</div>
<div id="block2">
    <a href="http://stackoverflow.com">link2</a>
    <a id="tips">just a bookmark</a>
</div>
HTML

doc = Nokogiri::HTML(html)

extraire tous les liens

Nous pouvons utiliser xpath ou css pour trouver tous les éléments, puis ne conserver que ceux qui ont un attribut href:

nodeset = doc.xpath('//a')      # Get all anchors via xpath
nodeset.map {|element| element["href"]}.compact  # => ["http://google.com", "http://stackoverflow.com"]

nodeset = doc.css('a')          # Get all anchors via css
nodeset.map {|element| element["href"]}.compact  # => ["http://google.com", "http://stackoverflow.com"]

Mais il existe un meilleur moyen: dans les cas ci-dessus, le .compact est nécessaire car les recherches renvoient également l'élément "juste un signet". Nous pouvons utiliser une recherche plus fine pour rechercher uniquement les éléments contenant un attribut href:

attrs = doc.xpath('//a/@href')  # Get anchors w href attribute via xpath
attrs.map {|attr| attr.value}   # => ["http://google.com", "http://stackoverflow.com"]

nodeset = doc.css('a[href]')    # Get anchors w href attribute via css
nodeset.map {|element| element["href"]}  # => ["http://google.com", "http://stackoverflow.com"]

trouver un lien spécifique

Pour trouver un lien dans le <div id="block2">

nodeset = doc.xpath('//div[@id="block2"]/a/@href')
nodeset.first.value # => "http://stackoverflow.com"

nodeset = doc.css('div#block2 a[href]')
nodeset.first['href'] # => "http://stackoverflow.com"

Si vous savez que vous recherchez un seul lien, vous pouvez utiliser at_xpath ou at_css à la place:

attr = doc.at_xpath('//div[@id="block2"]/a/@href')
attr.value          # => "http://stackoverflow.com"

element = doc.at_css('div#block2 a[href]')
element['href']        # => "http://stackoverflow.com"

trouver un lien à partir du texte associé

Que faire si vous connaissez le texte associé à un lien et souhaitez trouver son URL? Un petit xpath-fu (ou css-fu) est pratique:

element = doc.at_xpath('//a[text()="link2"]')
element["href"]     # => "http://stackoverflow.com"

element = doc.at_css('a:contains("link2")')
element["href"]     # => "http://stackoverflow.com"

trouver du texte à partir d'un lien

Et si vous voulez trouver le texte associé à un lien particulier? Pas de problème:

element = doc.at_xpath('//a[@href="http://stackoverflow.com"]')
element.text     # => "link2"

element = doc.at_css('a[href="http://stackoverflow.com"]')
element.text     # => "link2"

références utiles

En plus de la vaste documentation Nokorigi , je suis tombé sur quelques liens utiles en rédigeant ceci:

14
fearless_fool
doc = Nokogiri::HTML("HTML ...")
href = doc.css("div[id='block'] > a")
result = href['href'] #http://google.com
4
bor1s
data = '<html lang="en" class="">
    <head>
    <a href="https://example.com/9f40a.css" media="all" rel="stylesheet" /> link1</a>
    <a href="https://example.com/4e5fb.css" media="all" rel="stylesheet" />link2</a>
    <a href="https://example.com/5s5fb.css" media="all" rel="stylesheet" />link3</a>
   </head>
  </html>'

Voici mon exemple de code HTML à essayer ci-dessus:

doc = Nokogiri::HTML(data)
doc.xpath('//@href').map(&:value)
=> [https://example.com/9f40a.css, https://example.com/4e5fb.css, https://example.com/5s5fb.css]
1
Gagan Gami
document.css("#block a")["href"]

document est le code HTML Nokogiri analysé.

0
Oscar Albert