Поиск всех элементов перед элементом h2 в hpricot / nokogiri - PullRequest
2 голосов
/ 21 сентября 2009

Я пытаюсь разобрать запись Викисловаря, чтобы получить все определения на английском языке. Я могу восстановить все определения, проблема в том, что некоторые определения на других языках. Что я хотел бы сделать, так это каким-то образом получить только HTML-блок с английскими определениями. Я обнаружил, что в случае, когда есть записи на других языках, заголовок после английских определений может быть получен с помощью:

header = (doc/"h2")[3]

Так что я хотел бы искать только все элементы перед этим элементом заголовка. Я думал, что это возможно с header.preceding_siblings(), но, похоже, это не работает. Есть предложения?

Ответы [ 3 ]

2 голосов
/ 22 сентября 2009

Вы можете использовать шаблон посетителя с Nokogiri. Этот код удалит все, начиная с определения другого языка h2:

require 'nokogiri'
require 'open-uri'

class Visitor
  def initialize(node)
    @node = node
  end

  def visit(node)
    if @remove || @node == node
      node.remove
      @remove = true
      return
    end
    node.children.each do |child|
      child.accept(self)
    end
  end
end

doc = Nokogiri::XML.parse(open('http://en.wiktionary.org/wiki/pony'))
node = doc.search("h2")[2]  #In this case, the Italian h2 is at index 2.  Your page may differ

doc.root.accept(Visitor.new(node))  #Removes all page contents starting from node
1 голос
/ 18 августа 2011

Для Нокогири:

doc = Nokogiri::HTML(code)
stop_node = doc.css('h2')[3]
doc.traverse do |node|
  break if node == stop_node
  # else, do whatever, e.g. `puts node.name`
end

Это будет повторять все узлы, предшествующие любому узлу, который вы обозначите как stop_node в строке 2.

1 голос
/ 23 сентября 2009

В следующем коде используется Hpricot .
Он получает текст из заголовка для английского языка (h2) до следующего заголовка (h2) или до нижнего колонтитула, если больше нет языков:

require 'hpricot'
require 'open-uri'

def get_english_definition(url)
  doc = Hpricot(open(url))

  span = doc.at('h2/span[@class="mw-headline"][text()=English]')
  english_header = span && span.parent
  return nil unless english_header

  next_header_or_footer =
    Hpricot::Elements[*english_header.following_siblings].at('h2') ||
    doc.at('[@class="printfooter"]')

  Hpricot::Elements.expand(english_header.next_node,
                           next_header_or_footer.previous_node).to_s
end

Пример:

get_english_definition "http://en.wiktionary.org/wiki/gift"
...