2011-01-22 1 views
2

저는 루비와 프로그래밍 세계에 새로운 경험을하고 있습니다.Nokogiri XML 작성기로 HTML 스크래핑시 예상치 못한 결과가 발생합니다

내 목표는 테이블을 긁어내어 데이터를 XML 파일에 저장하는 것입니다. 필자가 작성한 간단한 스크립트는 두 가지를 모두 성공적으로 수행합니다. 내가 가지고있는 문제는 XML이 저장되는 방식입니다. 보고 있던 XML과 일치하지 않습니다.

나는 많은 예제, 튜토리얼 및 포럼을 뒤적었지만 아직 해결책을 찾지 못했다.

테이블에서 데이터를 가져 오는 더 좋은 방법에 대한 제안은 열려 있습니다. 특히 처음 세 열은 모두 내가 필요한 전부입니다. 도움!!! 여기

내 스크립트 :이 .xml 파일로 저장하거나 루비의 화면에 인쇄 여부

require 'nokogiri' 
require 'open-uri' 

url = "http://www.covers.com/pageLoader/pageLoader.aspx?page= 
/data/nba/team/pastresults/2010-2011/team404085.html" 
doc = Nokogiri::HTML(open(url)) 

builder = Nokogiri::XML::Builder.new do |xml| 
    xml.root { 
    xml.items { 
     doc.css('.data').each do |o| 
     xml.item_content = o 
     end 
    } 
    } 
end 

File.open('ATL.xml','w'){|f| f.write builder.to_xml} 

puts "Scrape Completed." 

의 XML은 다음과 같습니다

<?xml version="1.0"?> 
<root> 
    <items> 
    <item_content=>&lt;table cellpadding="2" cellspacing="1" class="data"&gt; 
&lt;tr class="datahead"&gt; 
&lt;td width="11%"&gt;Date&lt;/td&gt;&#xD; 
    &lt;td width="21%"&gt;Vs&lt;/td&gt;&#xD; 
    &lt;td width="18%"&gt;Score&lt;/td&gt;&#xD; 
    &lt;td width="27%"&gt;Type&lt;/td&gt;&#xD; 
    &lt;td width="13%"&gt;ATL Line&lt;/td&gt;&#xD; 
    &lt;td width="10%"&gt;O/U&lt;/td&gt;&#xD; 
    &lt;/tr&gt; 
&lt;tr class="datarow"&gt; 
&lt;td&gt;&#xD; 
     01/18/11&lt;/td&gt;&#xD; 
     &lt;td&gt;&#xD; 
     @ &lt;a href="/pageLoader/pageLoader.aspx?page=/data/nba/team/ 
team404171.html"&gt;Miami&lt;/a&gt;&#xD; 
     &lt;/td&gt;&#xD; 
     &lt;td&gt;&#xD; 
     W &lt;a href="/pageLoader/pageLoader.aspx?page=/data/nba/ 
results/2010-2011/boxscore795345.html"&gt;&#xD; 
     93-89&lt;/a&gt; (OT)&lt;/td&gt;&#xD; 
     &lt;td&gt;&#xD; 
     Regular Season&lt;/td&gt;&#xD; 
     &lt;td&gt;&#xD; 
     W 5.5&lt;/td&gt;&#xD; 
     &lt;td&gt;&#xD; 
     U 194&lt;/td&gt;&#xD; 
    &lt;/tr&gt; 

위의 코드는 그냥 스 니펫에는 여러 행이 있습니다. (총 44 개)
이렇게하는 가장 좋은 방법은 무엇입니까?

답변

3

출력으로 원하는 것이 명확하지 않습니다. XML에 포함 된 원본의 HTML을 원하거나 의 내용을의 HTML로 가져 오시겠습니까? 앞으로는 원하는 예제와 함께 문제의 예를 포함 시키면 도움이됩니다. 두 가지 문제를 해결합시다. 등호 태그 이름의 일부가 서명 당신은 단지 XML에서 HTML 노드의 내용을 원한다면

require 'nokogiri' 
doc = Nokogiri::XML <<ENDXML 
    <root> 
    <p class="foo">42</p> 
    <p class="bar">99</p> 
    <p class="foo">17</p> 
    </root> 
ENDXML 

builder = Nokogiri::XML::Builder.new do |xml| 
    xml.items { 
    doc.css('.foo').each{ |o| xml.item_content = o } 
    } 
end  
puts builder.to_xml 
#=> <?xml version="1.0"?> 
#=> <items> 
#=> <item_content=>&lt;p class="foo"&gt;42&lt;/p&gt;</item_content=> 
#=> <item_content=>&lt;p class="foo"&gt;17&lt;/p&gt;</item_content=> 
#=> </items> 

,하고 싶지 않았다 추정 : 첫째, 우리는과 같이 더 간단하게 문제를 재현 할 수 있습니다 다음 :

builder = Nokogiri::XML::Builder.new do |xml| 
    xml.items { 
    doc.css('.foo').each{ |o| xml.item_content(o.text) } 
    } 
end 
puts builder.to_xml 
#=> <?xml version="1.0"?> 
#=> <items> 
#=>   <item_content>42</item_content> 
#=>   <item_content>17</item_content> 
#=> </items> 

는 경우, 다른 한편으로는, 당신은 당신의 XML의 원시 HTML을 원하지 않았지만, 모든 엔티티를 원하지 않았다, 그것은에게 CDATA 블록합니다

builder = Nokogiri::XML::Builder.new do |xml| 
    xml.items { 
    doc.css('.foo').each{ |o| xml.item_content{ xml.cdata o } } 
    } 
end 
puts builder.to_xml 
#=> <?xml version="1.0"?> 
#=> <items> 
#=> <item_content><![CDATA[<p class="foo">42</p>]]></item_content> 
#=> <item_content><![CDATA[<p class="foo">17</p>]]></item_content> 
#=> </items> 

XML CDATA block을 사용하면 일반적으로 XML 마크 업용으로 예약 된 문자를 문자 엔티티로 표시 할 필요없이 사용할 수 있습니다.

+0

도움을 주신 Phrogz. 이 문제는 코드의 빌더 부분에있는 것처럼 보였습니다. HTML의 텍스트 만 필요했기 때문입니다. 다시 한 번 감사드립니다! – darren