【问题标题】:nokogiri + mechanize css selector by textnokogiri + mechanize css selector by text
【发布时间】:2014-03-18 09:14:43
【问题描述】:

我是 nokogiri 的新手,到目前为止最熟悉 CSS 选择器,我正在尝试从表格中解析信息,下面是表格的示例和我正在使用的代码,如果语句,因为它似乎返回了表的全部内容。

表:

<div class="holder">
  <div class ="row">
   <div class="c1">
     <!-- Content I Don't need -->
   </div>
   <div class="c2">
    <span class="data">
     <!-- Content I Don't Need -->
    <span class="data">
   </div>
 </div>
 ...
 <div class="row">
  <div class="c1">
   SPECIFIC TEXT
  </div>
  <div class="c2">
   <span class="data">
    What I want
   </span>
  </div>
 </div>
</div>

我的脚本:(如果在表中找到 SPECIFIC TEXT,它会返回每个“div.c2 span.data”变量 - 所以我要么搞砸了我对 do 循环或 if 语句的了解)

data = []
page.agent.get(url)
page.search('div.row').each do |row_data|
 if (row_data.search('div.c1:contains("/SPECIFIC TEXT/")').text.strip
  temp = row_data.search('div.c2 span.data').text.strip
  data << temp
 end
end

【问题讨论】:

  • 当前输出为&lt;!--Content I Don't Need --&gt;*n + What I want,预期输出为What I want
  • 是的..我明白了..请尝试以下解决方案
  • 表格中是否有可能会有多个 SPECIFIC TEXT?还是您只寻找一场比赛?
  • 我正在寻找一场比赛

标签: ruby parsing css-selectors nokogiri mechanize


【解决方案1】:

当您可以在单个 CSS 选择器中提取所需内容时,无需停止并插入 ruby​​ 逻辑。

data = page.search('div.row > div.c1:contains("SPECIFIC TEXT") + div.c2 span.data')

这将仅包括与选择器匹配的那些(例如,遵循特定文本)。

这就是你的逻辑可能出错的地方:

这段代码

if (row_data.search('div.c1:contains("SPECIFIC TEXT")'...
  temp = row_data.search('div.c2 span.data')...

首先在行中搜索特定文本,如果匹配,则返回与第二个查询匹配的所有行,第二个查询具有相同的起点。关键是上面 CSS 选择器中的+,它将返回紧随其后的元素(例如下一个兄弟元素)。当然,我假设下一个元素总是你想要的。

【讨论】:

  • 是的..你需要有+在那里..现在它可以工作了。
【解决方案2】:

我愿意

require 'nokogiri'

html = <<_
<div class="holder">
  <div class ="row">
   <div class="c1">
     <!-- Content I Don't need -->
   </div>
   <div class="c2">
    <span class="data">
     <!-- Content I Don't Need -->
    <span class="data">
   </div>
 </div>
 <div class="row">
  <div class="c1">
   SPECIFIC TEXT
  </div>
  <div class="c2">
   <span class="data">
    What I want
   </span>
  </div>
 </div>
</div>
_

doc = Nokogiri::HTML(html)
css_string = 'div.row > div.c1[text()*="SPECIFIC TEXT"] + div.c2 span.data'
doc.at(css_string).text.strip
# => "What I want"

这些选择器如何在这里工作 -

【讨论】:

  • 我原本是做temp = doc.at_css('div.row &gt; div.c1:contains("SPECIFIC TEXT") + div.c2 span.date').text.strip的,我从Mechanize得到了一个未定义的方法at_css错误
  • @Elliott 我这里特意用了at_css,如果要搜索多个节点,就用#css
  • @Arup,并非所有 Nokogiri 方法都可以从 Mechanize 访问。
  • @MarkThomas 感谢您告诉我,我已经在那里更改了。
  • 代替search(str).first,试试at(str)
猜你喜欢
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 2012-02-03
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
相关资源
最近更新 更多