2011-06-04 10 views
5

मैं नोकोगिरी के साथ एक HTML पृष्ठ पार्स करना चाहता हूं। पृष्ठ के एक भाग में एक सारणी है जो किसी भी विशिष्ट आईडी का उपयोग नहीं करती है। यह संभव तरह कुछ निकालने के लिए है:मैं नोकोगिरी के साथ एक सादे HTML तालिका का विश्लेषण कैसे करूं?

Today,3,455,34 
Today,1,1300,3664 
Today,10,100000,3444, 
Yesterday,3454,5656,3 
Yesterday,3545,1000,10 
Yesterday,3411,36223,15 

इस HTML से:

<div id="__DailyStat__"> 
    <table> 
    <tr class="blh"><th colspan="3">Today</th><th class="r" colspan="3">Yesterday</th></tr> 
    <tr class="blh"><th>Qnty</th><th>Size</th><th>Length</th><th class="r">Length</th><th class="r">Size</th><th class="r">Qnty</th></tr> 
    <tr class="blr"> 
     <td>3</td> 
     <td>455</td> 
     <td>34</td> 
     <td class="r">3454</td> 
     <td class="r">5656</td> 
     <td class="r">3</td> 
    </tr> 

    <tr class="bla"> 
     <td>1</td> 
     <td>1300</td> 
     <td>3664</td> 
     <td class="r">3545</td> 
     <td class="r">1000</td> 
     <td class="r">10</td> 
    </tr> 

    <tr class="blr"> 
     <td>10</td> 
     <td>100000</td> 
     <td>3444</td> 
     <td class="r">3411</td> 
     <td class="r">36223</td> 
     <td class="r">15</td> 
    </tr> 
    </table> 
</div> 

उत्तर

9

एक त्वरित और गंदा पहले पास के रूप में मुझे क्या करना चाहते हैं:

html = <<EOT 
<div id="__DailyStat__"> 
    <table> 
    <tr class="blh"><th colspan="3">Today</th><th class="r" colspan="3">Yesterday</th></tr> 
    <tr class="blh"><th>Qnty</th><th>Size</th><th>Length</th><th class="r">Length</th><th class="r">Size</th><th class="r">Qnty</th></tr> 
    <tr class="blr"> 
     <td>3</td> 
     <td>455</td> 
     <td>34</td> 
     <td class="r">3454</td> 
     <td class="r">5656</td> 
     <td class="r">3</td> 
    </tr> 

    <tr class="bla"> 
     <td>1</td> 
     <td>1300</td> 
     <td>3664</td> 
     <td class="r">3545</td> 
     <td class="r">1000</td> 
     <td class="r">10</td> 
    </tr> 

    <tr class="blr"> 
     <td>10</td> 
     <td>100000</td> 
     <td>3444</td> 
     <td class="r">3411</td> 
     <td class="r">36223</td> 
     <td class="r">15</td> 
    </tr> 
    </table> 
</div> 
EOT 

# Today    Yesterday 
# Qnty Size Length Length Size Qnty 
# 3 455 34  3454 5656 3 
# 1 1300 3664 3545 1000 10 
# 10 100000 3444 3411 36223 15 


require 'nokogiri' 

doc = Nokogiri::HTML(html) 

उपयोग सीएसएस खोजने के लिए तालिका की शुरुआत करें, और हमारे द्वारा कैप्चर किए जा रहे डेटा को पकड़ने के लिए कुछ स्थानों को परिभाषित करें:

table = doc.at('div#__DailyStat__ table') 

today_data  = [] 
yesterday_data = [] 
, तालिका में पंक्तियों से अधिक

लूप खारिज हेडर:

table.search('tr').each do |tr| 

    next if (tr['class'] == 'blh') 

प्रारंभ सरणियों प्रत्येक पंक्ति से उचित डेटा पर कब्जा करने, चुनिंदा उचित सरणी में डेटा धक्का:

today_td_data  = [ 'Today'  ] 
    yesterday_td_data = [ 'Yesterday' ] 

    tr.search('td').each do |td| 
    if (td['class'] == 'r') 
     yesterday_td_data << td.text.to_i 
    else 
     today_td_data << td.text.to_i 
    end 
    end 

    today_data  << today_td_data 
    yesterday_data << yesterday_td_data 

end 

और उत्पादन डेटा:

puts today_data.map{ |a| a.join(',') } 
puts yesterday_data.map{ |a| a.join(',') } 

> Today,3,455,34 
> Today,1,1300,3664 
> Today,10,100000,3444 
> Yesterday,3454,5656,3 
> Yesterday,3545,1000,10 
> Yesterday,3411,36223,15 

बस,मदद से आप कल्पना क्या "tr" पाश से हो रहा है निकास पर,और yesterday_data सरणियों सरणियों के- सरणियों की तरह देख रहे हैं:

[["Today", 3, 455, 34], ["Today", 1, 1300, 3664], ["Today", 10, 100000, 3444]] 

वैकल्पिक रूप से, बजाय "td" टैग से अधिक पाशन और टैग के लिए वर्ग संवेदन की, मैं "tr" की सामग्री को पकड़ा जा सकता था और फिर scan इस्तेमाल किया संख्या हड़पने के लिए और "आज" में जिसके परिणामस्वरूप सरणी और "कल" ​​सरणियों कटा हुआ:

tr_data = tr.text.scan(/\d+/).map{ |i| i.to_i } 

    today_td_data  = [ 'Today',  *tr_data[0, 3] ] 
    yesterday_td_data = [ 'Yesterday', *tr_data[3, 3] ] 

वास्तविक दुनिया विकास में, की तरह काम पर, मैं का उपयोग करें कि मैं क्या करने के बजाय पहले लिखा क्योंकि यह संक्षिप्त है।

और ध्यान दें कि मैंने XPath का उपयोग नहीं किया है। यह नोकोगिरी में XPath का उपयोग करने और इसे पूरा करने में बहुत ही कामयाब है, लेकिन सादगी के लिए मैं सीएसएस एक्सेसर्स पसंद करता हूं। XPath ने व्यक्तिगत "टीडी" टैग सामग्री तक पहुंचने की अनुमति दी होगी, लेकिन यह लाइन-शोर की तरह दिखने लगेगा, जो कोड लिखते समय हम टालना चाहते हैं, क्योंकि यह रखरखाव को प्रभावित करता है। मैं 'tr td.r' जैसे सही "टीडी" टैग पर ड्रिल करने के लिए सीएसएस का उपयोग भी कर सकता था, लेकिन मुझे नहीं लगता कि यह कोड में सुधार करेगा, यह सिर्फ ऐसा करने का एक वैकल्पिक तरीका होगा।

+0

धन्यवाद @ द-टिन-मैन। यह ठीक से काम करता है, बस मुझे कुछ त्रुटि प्राप्त करने के रूप में doc.css को doc.css में बदलना होगा। मेरे पास बस कुछ छोटी समस्या है, जिसे मैं हल करने की कोशिश करूंगा। मेरे पास इतने उत्साहित वोट देने के लिए पर्याप्त प्रतिष्ठा नहीं है :) – JraNil

+0

'सीटी और एक्सपीएथ दोनों के साथ काम करता है, लेकिन केवल नोड की पहली घटना देता है, इसलिए आपके पास एकाधिक 'टेबल' टैग हो सकते हैं। 'css' 'खोज' के लिए उपनाम है जो नोडसेट, AKA को नोड्स की एक सरणी देता है, इसलिए आपको परिणामों में अनुक्रमण करना होगा, या फिर उन पर पुन: प्रयास करना होगा। 'at_css' सीएसएस विशिष्ट 'एटी' के बराबर है। –

+0

@JraNil, इसके अलावा, एक एफवाईआई के रूप में, कोड आपके नमूना HTML के साथ काम करता है, इसलिए नमूना में कुछ याद आना चाहिए। यदि आप एक सटीक नमूना उत्पन्न करते हैं तो हम बेहतर उत्तर प्रदान कर सकते हैं। –

संबंधित मुद्दे