【问题标题】:match table row id's with a common prefix使用公共前缀匹配表行 ID
【发布时间】:2012-11-26 20:08:04
【问题描述】:

这可能只是一个语法问题。

我不清楚如何只匹配 id 以 rowId_ 开头的表行

agent = Mechanize.new
  pageC1 = agent.get("/customStrategyScreener!list.action") 

表格有 class=tableCellDT。

 pageC1.search('table.tableCellDT tr[@id=rowId_]')  # parses OK but returns 0 rows since rowId_ is not matched exactly.

 pageC1.search('table.tableCellDT tr[@id=rowId_*]')  # Throws an error since * is not treated like a wildcard string match

示例 HTML:

 <table id="row" cellpadding="5" class="tableCellDT" cellspacing="1">
<thead>
<tr>
<th class="tableHeaderDT">#</th>
<th class="tableHeaderDT sortable">
<a href="?d-16544-s=1&amp;d-16544-o=2&amp;d-16544-p=1">Screener</a></th>
<th class="tableHeaderDT sortable">
<a href="?d-16544-s=2&amp;d-16544-o=2&amp;d-16544-p=1">Strategy</a></th>
<th class="tableHeaderDT"> </th></tr></thead>
<tbody>
<tr id="rowId_BullPut" class="odd">
<td>   1  </td>
<td>   Bull</td>
<td></td>
<td><a href="link1?model.itemId=2262">Edit</a>&nbsp;&nbsp;
            <a href="javascript:deleteScreener('link2?model.itemId=2262');">Delete</a>&nbsp;&nbsp;
            <a href="link3?model.itemId=2262&amp;amp;model.source=list">View</a>&nbsp;&nbsp;
            </td></tr>

注意

pageC1Mechanize::Page 对象,而不是 Nokogiri 任何东西。抱歉,一开始不清楚。 Mechanize::Page 没有 #css 或 #xpath 方法,但可以从中提取 Nokogiri 文档(无论如何在内部使用)。

【问题讨论】:

  • 你要提取什么?
  • 会有其他行的 id 不是 ="rowId_xxxx"。那些我需要忽略的。例如。忽略&lt;tr id="otherPrefix_Credit" class="odd"&gt;
  • 我明白这一点,但想知道根据您的输入您想要什么输出。
  • 虽然不在问题中,但最终,对于每个 rowId_* tr,我需要在 tr 的 id、单元格 2 的文本和单元格 4 的第三个链接目标中提取 rowId_ 之后的后缀(其中 text= “查看”)。
  • Nokogiri 行数组很好,就像pageC1.search('table.tableCellDT tr') 返回的那样,或者数组数组(每个元素都包含这三个东西的字符串)

标签: ruby nokogiri mechanize


【解决方案1】:

要获取id 以“rowId_”开头的tr 元素:

pageC1.search('//tr[starts-with(@id, "rowId_")]')

【讨论】:

  • pageC1.search('tr[starts-with(@id, "rowId")]') 得到我Nokogiri::XML::XPath::SyntaxError: Invalid number of arguments: //tr[starts-with(., @id, "rowId")] from /var/lib/gems/1.9.1/gems/nokogiri-1.5.5/lib/nokogiri/xml/node.rb:159:in evaluate' `
  • 我正在检查starts-withcontains w3schools.com/xpath/xpath_functions.asp;知道与 Ruby/Mechanize/Nokogiri 更相关的更好参考吗?
  • 奇怪的是它正在修改您的starts-with() 以包含“.”作为第一个参数。尝试专门使用xpath() 方法。如果这不起作用,请尝试'tr[id[starts-with(.,"rowId_")]]'
  • 我认为问题在于使用search Nokogiri 不知道您使用的是 CSS 还是 XPath,它会将您的 XPath 查询转换为 CSS。
  • 似乎我现在需要从 Mechanize Page 对象中提取 Nokogiri 文档。 pageC1.xpath('tr[starts-with(@id, "rowId_")]') 让我 NoMethodError: undefined method xpath' 获得 #<:page:0xa0c2790>`
【解决方案2】:

你想要 CSS3 attribute starts-with selector:

pageC1.css('table.tableCellDT tr[id^="rowId_"]')

或 XPath starts-with() 函数:

pageC1.xpath('.//table[@class="tableCellDT"]//tr[starts-with(@id,"rowId_")]')

虽然 Nokogiri Node#search 方法会根据您编写的内容智能地在 CSS 或 XPath 选择器语法之间进行选择,但这并不意味着您可以在同一个查询中混合使用 CSS 和 XPath 选择器语法。

在行动:

>> require 'nokogiri'
#=> true

>> doc = Nokogiri.HTML <<ENDHTML; true #hide output from IRB
">> <table class="foo"><tr id="rowId_nonono"><td>Nope</td></tr></table>
">> <table class="tableCellDT">
">>   <tr id="rowId_yesyes"><td>Yes1</td></tr>
">>   <tr id="rowId_andme2"><td>Yes2</td></tr>
">>   <tr id="rowIdNONONO"><td>Needs underscore</td></tr>
">> </table>
">> ENDHTML
#=> true

>> doc.css('table.tableCellDT tr[id^="rowId_"]').map(&:text)
#=> ["Yes1", "Yes2"]

>> doc.xpath('.//table[@class="tableCellDT"]//tr[starts-with(@id,"rowId_")]').map(&:text)
#=> ["Yes1", "Yes2"]

【讨论】:

  • 我更喜欢 CSS 方法,但是:NoMethodError: undefined method css' for #<:page:0xa0c2790>`
  • @Marcos 抱歉,我没有看到您使用的是 Mechanize。只需使用 #search 和 CSS 语法即可。
  • 感谢您帮助指出正确的方向!我将尝试将我拥有的 pageC1 对象内联到 Nokogiri::Doc 中,这是使用 #css 和 #xpath 方法所需的。
【解决方案3】:

感谢 http://nokogiri.org/Nokogiri/XML/Node.html#method-i-css

以及上面的答案,这是解决我的问题的最终代码,即只获取我需要的行,然后只从每个行中读取某些信息:

 pageC1.search('//tr[starts-with(@id, "rowId_")]').each do |row|

# Read the string after _ in rowId_, part of the "id" in <tr>
    rid = row.attribute("id").text.split("_")[1] # => "BullPut"

# Get the URL of the 3rd <a> link in <td> cell 4    
    link = row.css("td[4] a[3]")[0].attributes["href"].text # => "link3?model.itemId=2262&amp;amp;model.source=list"
 end

【讨论】:

    猜你喜欢
    • 2015-08-16
    • 1970-01-01
    • 2021-09-11
    • 2013-06-03
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多