Как искать "текст", а затем пересекать DOM из найденного node?
У меня есть веб-страница, с которой мне нужно очистить некоторые данные. Проблема в том, что каждая страница может иметь или не иметь конкретных данных, или она может иметь дополнительные данные выше или ниже этого в DOM, и нет идентификаторов CSS, о которых можно говорить.
Обычно я мог использовать либо идентификаторы CSS, либо XPath для доступа к node, который я ищу. У меня нет такого варианта в этом случае. То, что я пытаюсь сделать, это поиск текста "метки", а затем захват данных в следующем <TD>
node:
<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:']")
чтобы получить node непосредственно перед данными, которые мне нужны, но я не уверен, как перемещаться оттуда.
Ответы
Ответ 1
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 next_element():"
puts el.parent.next_element
# Output:
#
# Found element:
# <b>Name:</b>
#
# Parent element:
# <td>
# <b>Name:</b>
# </td>
#
# Parent next_element():
# <td>Joe Smith <small><a href="/Joe"><img src="/joe.png"></a></small>
# </td>
Обратите внимание, что поскольку текст находится внутри тегов <b></b>
, вы должны подняться на уровень (до найденного элемента parent <td>
), прежде чем сможете перейти к следующему брату. Если структура HTML нестабильна, вам нужно будет найти первого родителя, который является <td>
, и оттуда оттуда.
Ответ 2
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"
Ответ 3
Вы можете выполнить весь поиск в одном выражении с помощью синтаксиса xpath parent/following_sibling:
>> 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>"