2009-04-09 2 views
2

hpricot을 사용하여 테이블 기반 웹 사이트에서 정보를 추출하려고합니다. 나는 FireBug로 XPath를 얻는다.hpricot with firebug 's XPath

/html/body/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr/td[2]/table/tbody/tr[3]/td/table[3]/tbody/tr 

이 ... 분명히, 파이어 버그의 XPath는이 렌더링 된 HTML의 경로 및 사이트에서 어떤 실제 HTML입니다 작동하지 않습니다. 나는 tbody 제거 문제를 해결할 수 있습니다 읽었습니다. 내가 좀 더 연구를 ... 작동하지 않습니다 아직

/html/body/div/table/tr/td/table/tr[2]/td/table/tr/td[2]/table/tr[3]/td/table[3]/tr 

그리고, 어떤 사람들은 숫자를 제거 자신의 XPath를 얻을보고, 그래서 나는 이것을 시도 :

나는 함께 시도

: 아직

행운

/html/body/div/table/tr/td/table/tr/td/table/tr/td/table/tr/td/table/tr 
...

그래서 나는이 같은 단계별로하기로 결정

내가 필요로하는 정보는 bbb에서 찾을 수 있지만 ccc에서는 찾을 수 없습니다.

길거나 복잡한 XPath로 HTML을 스크랩하는 데 더 좋은 도구가 있습니까?

답변

1

XPath 대신 hpricot의 CSS 구문 분석을 사용하는 것이 좋습니다. _why는 가능한 한 XPath를 한 번에 depricating하는 것에 대해 이야기하고있었습니다.

데이터의 더 좋은 예가 있습니까? 그들은 쉽게 참조 할 수있는 CSS 태그를 사용합니까?

이 같은 검색을 훨씬 쉽게 :이 Hpricot을 논의했다 (지금은 찾을 수 없습니다) _why의 웹 사이트의 이전 페이지, 그리고 의견의 일부는 방법을 암시

doc.search("#id_tag > table > tr.class_tag > td").each do |aaa| 
    aaa.search("blah > blah").each do |bbb| 
     bbb.inner_html 

자신과 비슷한 중첩 된 검색을 수행 할 때 CSS 버전이 XPath보다 더 나은 선택이었습니다.

위시 나는 더 나은 대답을 줄 수는 있지만, CSS 방법을 사용하고 XPath로 머리카락을 찢어 버리는 방법을 직접 확인하는 것이 좋습니다. 지금이 위대한 도구를 사용하여 CSS와 I "그림"을 사용하고

1

그것은 Nokogiri가 Hpricot을 동일한 API를 사용한다는 지적 아마도 가치뿐만 아니라 XPath 식을 지원합니다.

4

문제는 XPather (또는 방화 광 XPath)에 있습니다. Firefox 내부적으로 HTML에 tbody 요소가있는 경우에도 형식이 잘못된 표를 고쳐서 tbody 요소를 수정한다고 생각합니다. Nokogiri는 그렇게하지 않고 tr 태그를 테이블 내부에 넣을 수 있습니다.

그래서 경로는 다음과 같이 노코 기리 보이는 큰 기회가있다 :

/html/body/div/table/tr/td/table/tr[2]/td/table/tr/td[2]/table/tr[3]/td/table[3]/tr 

및 그 노코 기리가 그것을 :) 받아 들일 것입니다 방법

require 'open-uri' 
require 'nokogiri' 

class String 
    def relative_to(base) 
    (base == self[0..base.length-1]) && 
     self[base.length..-1] 
    end 
end 

module Importer 
    module XUtils 
    module_function 

    def match(text, source) 
     case text 
     when String 
     source.include? text 
     when Regexp 
     text.match(source) 
     when Array 
     text.all? {|tt| source.include?(tt)} 
     else 
     false 
     end 
    end 

    def find_xpath (doc, start, texts) 
     xpath = start 
     found = true 

     while(found) 
     found = [:inner_html, :inner_text].any? do |m| 
      doc.xpath(xpath+"/*").any? do |tag| 
      tag_text = tag.send(m).strip.gsub(/[\302\240]+/, ' ') 
      if tag_text && texts.all?{|text| match(text, tag_text)} 
       xpath = tag.path.to_s 
      end 
      end 
     end 
     end 

     (xpath != start) && xpath 
    end 

    def fetch(url) 
     Nokogiri::HTML(open(url).read) 
    end 
    end 
end 
을 확인 할 수 있습니다

웹 스크래핑과 데이터 마이닝을 할 때 Nokogiri와 함께 작업 할 수 있도록이 작은 모듈을 작성했습니다.

기본적인 사용법 :

include XUtils 
doc = fetch("http://some.url.here") # http:// is impotrtant! 

base = find_xpath(doc, '/html/body', ["what to find1", "What to find 2"]) # when you provide array, then it'll find element conaining ALL words 

precise = find_xpath(doc, base, "what to find1") 
precise.relative_to base 

행운

0

HTML 코드에서 아니오 TBODY 태그가 없습니다. 방화 광이 자동으로 생성합니다.