Как мне найти «текст», а затем пересечь DOM от найденного узла? - PullRequest
16 голосов
/ 25 апреля 2011

У меня есть веб-страница, с которой мне нужно почистить некоторые данные.Проблема в том, что каждая страница может иметь или не иметь определенные данные, или она может иметь дополнительные данные выше или ниже ее в DOM, и нет никаких идентификаторов CSS, о которых можно было бы говорить.

Обычно я могу использовать либо CSS-идентификаторы, либо XPath, чтобы добраться до нужного мне узла.У меня нет этого варианта в этом случае.Я пытаюсь найти текст «метки», а затем получить данные в следующем <TD> узле:

<tr> 
    <td><b>Name:</b></td> 
    <td>Joe Smith <small><a href="/Joe"><img src="/joe.png"></a></small></td> 
</tr>

. В приведенном выше HTML-коде я буду искать:

doc.search("[text()*='Name:']")

чтобы получить узел непосредственно перед нужными мне данными, но я не уверен, как оттуда перейти.

Ответы [ 3 ]

25 голосов
/ 25 апреля 2011

next_element - это, вероятно, метод, который вы ищете.

require 'nokogiri'

data = File.read "html.htm"

doc  = Nokogiri::HTML data

els  = doc.search "[text()*='Name:']"
el   = els.first

puts "Found element:"
puts el
puts

puts "Parent element:"
puts el.parent
puts

puts "Parent's next_element():"
puts el.parent.next_element

# Output:
#
# Found element:
# <b>Name:</b>
#
# Parent element:
# <td> 
#     <b>Name:</b>
# </td>
#
# Parent's next_element():
# <td>Joe Smith <small><a href="/Joe"><img src="/joe.png"></a></small>
# </td>

Обратите внимание, что, поскольку текст находится внутри тегов <b></b>, вы должны подняться на уровень выше.(до родителя найденного элемента <td>), прежде чем вы сможете перейти к следующему брату.Если структура HTML нестабильна, вам нужно найти первого родителя <td> и перейти оттуда.

2 голосов
/ 10 марта 2013
require 'nokogiri'

html = '
<html>
  <body>
    <p>foo</p>
    this text
    <p>bar</p>
  </body>
</html>
'

doc = Nokogiri::HTML(html)
doc.at('p:contains("foo")').next_sibling.text.strip
=> "this text"
0 голосов
/ 30 ноября 2013

Вы можете выполнить весь поиск в одной инструкции, используя синтаксис родителя / follow_sibling в xpath:

>> require 'nokogiri' 
=> true   
>> html = <<HTML
<tr> 
    <td><b>Name:</b></td> 
    <td>Joe Smith <small><a href="/Joe"><img src="/joe.png"></a></small></td> 
</tr>
HTML
>> doc = Nokogiri::HTML(html)

>> doc.at_xpath("//*[text()='Name:']/../following-sibling::*").to_s
=> "<td>Joe Smith <small><a href=\"/Joe\"><img src=\"/joe.png\"></a></small>\n</td>"
...