Поскольку у нас нет класса CSS, атрибута id
или другой семантической разметки, мы вместо этого ищем что-то, что, вероятно, не изменится в этом документе, чтобы привязать наш поиск.В этом случае я подозреваю, что метка «Deliver To:» всегда будет стоять перед желаемым тд.Итак:
require 'nokogiri'
html = # Fetch either from http via open-uri's open() or from file via IO.read()
doc = Nokogiri.HTML(html)
delivery = doc.at_xpath '//td[preceding-sibling::td[b="Deliver To:"]]/text()'
p delivery.content
#=> "ANYWHERE, NY"
Это выражение XPath говорит:
//
- на любом уровне, td
- найдите мне элемент с именем td
[…]
- но только если… preceding-sibling::
- у него есть предшествующий брат td
- это элемент с именем td
[…]
- но только если… b
- у него есть дочерний элемент с именем b
="Deliver To:"
- текстовое содержимое которого равно этой строке
/text()
- и затем найдите мне дочерний текстовый узел (узлы) этого td
.
Поскольку мы использовали at_xpath
вместо xpath
, Nokogiri возвращает первый соответствующий узел, который он может найти - который в данном случае оказывается единственным дочерним текстовым узлом этого тд - вместо массива узлов.
В случае, если <td>
может иметь разметку, такую как <td…>ANYWHERE,<br>NY</td>
, вы можете изменить выражение, чтобы пропустить завершающий /text()
(так, чтобы вы выбрали только сам <td>
), а затем использовать метод text
дляпринести комвон там отображается текст.