如何使用 Nokogiri(以及 XPATH 和 CSS)提取 HTML 链接和文本

How to extract HTML links and text using Nokogiri (and XPATH and CSS)

(更新:这个答案是从 Nokogiri 的角度写的,但如果您正在寻找特定查询的 XPATH 或 CSS 语法,它也很有用。)

我喜欢 Nokogiri -- 它是从 XML 和 HTML 文档中提取元素的绝佳工具。网上的例子虽然不错,但大多是展示如何操作XML个文档。

如何使用 Nokogiri 从 HTML 中提取 links 和 link 文本?

这是一个最初为响应 Getting attribute's value in Nokogiri to extract link URLs 而编写的小示例,在此处以社区 Wiki 样式提取以供参考。

以下是在 HTTP 中解析 link 时可能执行的一些常见操作,在 cssxpath 语法中均有显示。

从这个片段开始:

require 'rubygems'
require 'nokogiri'

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

doc = Nokogiri::HTML(html)

正在提取所有 links

我们可以使用 xpath 或 css 找到所有 <a> 元素,然后仅保留具有 href 属性的元素:

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

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

在上述情况下,.compact 是必需的,因为除其他元素外,还搜索 <a> 元素 returns 和 "just a bookmark" 元素。

但我们可以使用更精确的搜索来查找仅包含 href 属性的元素:

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

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

寻找特定的 link

<div id="block2">

中找到一个link
nodeset = doc.xpath('//div[@id="block2"]/a/@href')
nodeset.first.value # => "http://whosebug.com"

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

如果您知道自己只搜索一个 link,则可以使用 at_xpathat_css

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

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

从相关文本中找到 link

如果您知道与 link 关联的文本并想找到它的 url 怎么办?一点 xpath-fu(或 css-fu)就派上用场了:

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

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

从 link

中查找文本

为了完整起见,以下是您如何获取与特定 link 关联的文本:

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

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

有用的参考资料

除了广泛的 Nokorigi documentation,我在撰写本文时遇到了一些有用的 link: