【问题标题】:Extract specific nodes in HTML using Nokogiri使用 Nokogiri 提取 HTML 中的特定节点
【发布时间】:2016-01-18 06:25:52
【问题描述】:

我想在这个 ruby​​ 脚本中使用 Nokogiri 从 HTML 中提取一些值:

#!/usr/bin/ruby
require 'Nokogiri'

doc = Nokogiri::HTML(<<-END_OF_HTML)
  <html>
  <meta content="text/html; charset=UTF-8"/>
  <body style='margin:20px'>
    <p>The following user has registered a device, click on the link below to review the user and make any changes if necessary.</p>
    <ul style='list-style-type:none; margin:25px 15px;'>
      <li><b>User name:</b> Test User</li>
      <li><b>User email:</b> test@abc.com</li>
      <li><b>Identifier:</b> abc123def132afd1213afas</li>
      <li><b>Description:</b> Tom's iPad</li>
      <li><b>Model:</b> iPad 3</li>
      <li><b>Platform:</b> </li>
      <li><b>App:</b> Test app name</li>
      <li><b>UserID:</b> </li>
     </ul>
    <p>Review user: https://cirrus.app47.com/users?search=test@abc.com</p>            <hr style='height=2px; color:#aaa'/>
        <p>We hope you enjoy the app store experience!</p>
        <p style='font-size:18px; color:#999'>Powered by App47</p>
      <img src='https://cirrus.app47.com/notifications/562506219ac25b1033000904/img' alt=''/></body></html>
END_OF_HTML

具体来说,我想获取一些列表成员的值,例如"Identifier:""User name:",并将它们存储在字符串中。

我确定我需要使用xpath,但仅此而已。我的理解是xpath做节点选择。

我需要用xpath 指定什么,然后如何将选择放入一些变量中?

完整解决方案

最后我真的问了两个问题。

问题 1(隐式):如何查看使用 xpath 的搜索结果?

doc.xpath("SPECIFY_SEARCH_HERE").each do |node|
puts node
end

这是可行的,因为xpath 返回一个您可以解析的数组,然后您可以对结果做您想做的事情(在我的例子中,打印)。

问题 2:如何获取特定列表项的值?

str = doc.xpath("//ul/li[contains(b, 'Identifier')]/text()").to_s.strip

我对这一行的分析是有限的,但看起来是这样的:

  1. 使用以下命令查找 li 子键的位置://ul/li
  2. 选择包含“标识符”的粗体键 (b)
  3. 从#2 中提取选择的值:/text()
  4. .to_s.strip 将所选内容转换为字符串并删除前导/尾随空格

对于更精通 HTML/Ruby/Xpath 的任何人,请随时更新解释以确保准确性。

【问题讨论】:

  • 你试过什么?这是非常基本的。您可以使用 XPath(使用 .xpath)或 CSS 样式选择器(使用 .css)。你看过官方Nokogiri Tutorials吗?
  • 特别是doc.xpath("//Identifier:") - 但由于“:”而出现错误。也许有办法逃脱它?这些教程让我头晕目眩,因为我并不真正了解 HTML 结构,因此很难确定我可以信任的内容。

标签: html ruby xpath html-parsing nokogiri


【解决方案1】:

这将返回您要求的两个值

//ul/li[contains(b, 'Identifier') or contains(b, 'User name')]/text()

当然你可以修改xpath,一次只能得到1个值。

//ul/li[contains(b, 'Identifier')]/text()

【讨论】:

  • 我的主要问题是冒号 (':') 字符产生语法错误。有没有办法摆脱它?
  • 我已经更新了答案。只使用包含而不使用:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2015-02-16
  • 2013-08-29
  • 2019-01-27
相关资源
最近更新 更多