2009-09-21 3 views
2

모든 영어 정의를 검색하기 위해 위키 백과 항목을 구문 분석하려고합니다. 나는 모든 정의를 되 찾을 수 있으며, 일부 정의는 다른 언어로되어있다. 내가하고 싶은 것은 어쨌든 영어 정의가있는 HTML 블록 만 가져옵니다. 나는 다른 언어 항목이있는 경우, 영어 정의 후 헤더로 검색 할 수 있다는 것을 발견했다 : hpricot/nokogiri에서 h2 요소 앞에있는 모든 요소 검색

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

그래서 난 단지이 헤더 요소 전에 모든 요소를 ​​검색하고 싶습니다. header.preceding_siblings()으로 가능할 수도 있다고 생각했지만 작동하지 않는 것 같습니다. 어떤 제안?

답변

2

Nokogiri로 방문자 패턴을 사용할 수 있습니다. 다음 코드는 Hpricot을을 사용

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

:이 코드는 다른 언어의 정의의 H2부터 모든 것을 제거합니다.
그것은 다음 헤더까지 영어 (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" 
은 노코 기리를 들어
1

:

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 

이 모든 노드는 사이트 디자인 어떤 노드 앞을 반복합니다 2 행에 stop_node으로 표시하십시오.