Борясь с этим вопросом в различных формах, я решил написать себе учебник, замаскированный под ответ.Это может быть полезно для других.
Начиная с этого фрагмента:
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)
извлечение всех ссылок
Мы можем использовать xpath или css, чтобы найти все элементы изатем оставьте только те, которые имеют атрибут 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"]
Но есть и лучший способ: в вышеприведенных случаях необходим .compact
, потому что поиск возвращает элемент «просто закладка»также.Мы можем использовать более точный поиск, чтобы найти только элементы, которые содержат атрибут 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"]
поиск конкретной ссылки
Чтобы найти ссылку в <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"
Если вы знаете, что ищете только одну ссылку, вы можете использовать at_xpath
или at_css
вместо этого:
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"
найти ссылку из связанного текста
Что если вы знаете текст, связанный со ссылкой, и хотите найти ее URL?Немного xpath-fu (или css-fu) пригодится:
element = doc.at_xpath('//a[text()="link2"]')
element["href"] # => "http://stackoverflow.com"
element = doc.at_css('a:contains("link2")')
element["href"] # => "http://stackoverflow.com"
найти текст по ссылке
А что, если вы хотите найти текст, связанный с конкретной ссылкой?Не проблема:
element = doc.at_xpath('//a[@href="http://stackoverflow.com"]')
element.text # => "link2"
element = doc.at_css('a[href="http://stackoverflow.com"]')
element.text # => "link2"
полезные ссылки
В дополнение к обширной документации Nokorigi , я натолкнулся на несколько полезных ссылок при написании этого: