2012-04-02 14 views
13

मेरे पास एक सारणी है जिसे मुझे पार्स करने की आवश्यकता है, विशेष रूप से यह 4 सप्ताह के साथ एक स्कूल शेड्यूल है, और हर सप्ताह के लिए 5 ब्लॉक दिन है। मैंने इसे पार्स करने का प्रयास किया है, लेकिन ईमानदारी से बहुत दूर नहीं मिला है क्योंकि मैं पंक्ति और कोस्पेन विशेषताओं से निपटने के तरीके से फंस गया हूं, क्योंकि उनका अनिवार्य रूप से मतलब है कि डेटा की कमी है जिसे मुझे जारी रखने की आवश्यकता है।पंक्ति और कोस्पैन के साथ एक तालिका को पार्स करना

<tr> 
    <td colspan="2" rowspan="4">#1</td> 
    <td rowspan="4">#2</td> 
    <td rowspan="2">#3</td> 
    <td rowspan="2">#4</td> 
</tr> 

<tr> 
</tr> 

<tr> 
    <td rowspan="2">#5</td> 
    <td rowspan="2">#6</td> 
</tr> 

<tr> 
</tr> 

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

[[1,1,2,3,4], 
[1,1,2,3,4], 
[1,1,2,5,6], 
[1,1,2,5,6]] 

अभी मैं

मुझे क्या करना चाहते हैं का एक उदाहरण के रूप में, यहाँ एक मेज है इस तरह के एक फ्लैट सूची प्राप्त करना:

[1,2,3,4,5,6] 

लेकिन शब्दकोश रूप में, कितने कॉलम और ro के बारे में जानकारी के साथ यह spans, इसका विवरण और इसमें किस हफ्ते है।

स्पष्ट रूप से इसे रोशन/कोस्पैन की हर संभावना के लिए और उसी तालिका में कई सप्ताह के लिए काम करने की आवश्यकता है।

एचटीएमएल उतना स्वच्छ नहीं है जितना मैंने इसे चित्रित किया है, वहां बहुत सारी विशेषताएं हैं जिन्हें मैंने छोड़ा है, और पाठ स्पष्ट रूप से साफ कटौती के रूप में 1,2,3,4 के रूप में नहीं बल्कि इसके ब्लॉक वर्णनात्मक पाठ। लेकिन अगर मैं इस भाग को हल कर सकता हूं तो यह पहले से लिखे गए शब्दों में शामिल होना आसान होना चाहिए।

मैं ऐसा करने के लिए lxml.html और पायथन का उपयोग कर रहा हूं, लेकिन यदि यह एक आसान समाधान प्रदान करता है तो मैं अन्य मॉड्यूल का उपयोग करने के लिए खुला हूं।

मुझे उम्मीद है कि कोई मेरी मदद कर सकता है, क्योंकि मुझे सच में नहीं पता कि क्या करना है।

संपादित करें:

<table> 
    <tr> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
     <td rowspan="4">Thing</td> 
     <td> </td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
     <td> </td> 
    </tr> 
</table> 

यह मैं कुछ समस्याओं का कारण है, इस outputting है

[' ', ' ', ' ', 'Thing', ' '] 
[' ', ' ', ' ', ' ', ' '] 
[' ', ' ', ' ', ' ', ' '] 
[' ', ' ', ' ', ' ', ' '] 
reclosedev द्वारा प्रदान की कोड, क्या मैं तो यह

आउटपुट यह अनुकूल करने के लिए बदलने की जरूरत है ऐसा करने के साथ

[' ', ' ', ' ', 'Thing', ' '] 
[' ', ' ', ' ', 'Thing', ' '] 
[' ', ' ', ' ', 'Thing', ' '] 
[' ', ' ', ' ', 'Thing', ' '] 

इसके बजाय?

EDIT2: reclosedev के नए समारोह का उपयोग करना, यह एक समाधान के करीब पहुंच रहा है, लेकिन अभी भी ऐसे मामलों में जहां इसे सही ढंग से कोशिकाओं को जगह करने में विफल रहता है:

<table> 
    <tr> 
     <td> </td> 
     <td rowspan="2"> DMAT Aud. 6 </td> 
     <td rowspan="4"> Exam</td> 
     <td rowspan="2"> DMAT Aud. 7</td> 
     <td> </td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td rowspan="2"> CART Aud. 4</td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td rowspan="2"> CART Aud. 4</td> 
     <td rowspan="2"> OOP Aud. 7</td> 
    </tr> 
    <tr> 
     <td> </td> 
     <td> </td> 
    </tr> 
</table> 
इस के साथ

, मूल तालिका में इस तरह के रूप में यह पता चलता है:

[ 
[' ', ' DMAT Aud. 6 ', ' Exam', ' DMAT Aud. 7', ' '], 
[' ', ' DMAT Aud. 6 ', ' Exam', ' DMAT Aud. 7', ' CART Aud. 4'], 
[' ', ' CART Aud. 4' , ' Exam', ' OOP Aud. 7' , ' CART Aud. 4'], 
[' ', ' CART Aud. 4' , ' Exam', ' OOP Aud. 7' , ' '] 
] 

लेकिन नए कॉल आउटपुट इस:

[ 
[' ', ' DMAT Aud. 6 ', ' Exam', ' DMAT Aud. 7', ' '], 
[' ', ' DMAT Aud. 6 ', ' Exam', ' DMAT Aud. 7', ' CART Aud. 4'], 
[' ', ' CART Aud. 4' , ' Exam', ' CART Aud. 4', ' OOP Aud. 7'], 
[' ', ' CART Aud. 4' , ' Exam', ' OOP Aud. 7' , ' '] 
] 
+3

यह वास्तव में हमारी मदद करेगा यदि आप हमें दिखा सकते हैं कि आप वर्तमान में किस कोड का उपयोग कर रहे हैं और आप वास्तव में क्या आउटपुट प्राप्त कर रहे हैं, आउटपुट की बजाय जो आप प्राप्त कर रहे हैं उसके समान है। –

उत्तर

11

अद्यतन (हटाया पिछले समारोह)

UPDATE2 तय की और सरल बनाया।

मेरा पहला कार्य गलत था। इधर, एक और एक है यह काम कर रहा है, लेकिन जरूरत है परीक्षण:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
from collections import defaultdict 


def table_to_list(table): 
    dct = table_to_2d_dict(table) 
    return list(iter_2d_dict(dct)) 


def table_to_2d_dict(table): 
    result = defaultdict(lambda : defaultdict(unicode)) 
    for row_i, row in enumerate(table.xpath('./tr')): 
     for col_i, col in enumerate(row.xpath('./td|./th')): 
      colspan = int(col.get('colspan', 1)) 
      rowspan = int(col.get('rowspan', 1)) 
      col_data = col.text_content() 
      while row_i in result and col_i in result[row_i]: 
       col_i += 1 
      for i in range(row_i, row_i + rowspan): 
       for j in range(col_i, col_i + colspan): 
        result[i][j] = col_data 
    return result 


def iter_2d_dict(dct): 
    for i, row in sorted(dct.items()): 
     cols = [] 
     for j, col in sorted(row.items()): 
      cols.append(col) 
     yield cols 


if __name__ == '__main__': 
    import lxml.html 
    from pprint import pprint 

    doc = lxml.html.parse('tables.html') 
    for table_el in doc.xpath('//table'): 
     table = table_to_list(table_el) 
     pprint(table) 

tables.html:

<table border="1"> 
    <tr> 
     <td>1 </td> 
     <td>1 </td> 
     <td>1 </td> 
     <td rowspan="4">Thing</td> 
     <td>1 </td> 
    </tr> 
    <tr> 
     <td>2 </td> 
     <td>2 </td> 
     <td>2 </td> 
     <td>2 </td> 
    </tr> 
    <tr> 
     <td>3 </td> 
     <td>3 </td> 
     <td>3 </td> 
     <td>3 </td> 
    </tr> 
    <tr> 
     <td>4 </td> 
     <td>4 </td> 
     <td>4 </td> 
     <td>4 </td> 
    </tr> 
</table> 

<table border="1"> 
<tr> 
    <td colspan="2" rowspan="4">#1</td> 
    <td rowspan="4">#2</td> 
    <td rowspan="2">#3</td> 
    <td rowspan="2">#4</td> 
</tr> 
<tr></tr> 
<tr> 
    <td rowspan="2">#5</td> 
    <td rowspan="2">#6</td> 
</tr> 
<tr></tr> 
</table> 

आउटपुट:

[['1 ', '1 ', '1 ', 'Thing', '1 '], 
['2 ', '2 ', '2 ', 'Thing', '2 '], 
['3 ', '3 ', '3 ', 'Thing', '3 '], 
['4 ', '4 ', '4 ', 'Thing', '4 ']] 
[['#1', '#1', '#2', '#3', '#4'], 
['#1', '#1', '#2', '#3', '#4'], 
['#1', '#1', '#2', '#5', '#6'], 
['#1', '#1', '#2', '#5', '#6']] 
+0

कुछ लोगों ने इसे करने के लिए इसे प्राप्त करने के लिए कुछ लिया, विशेष रूप से मुझे पूरी तालिका को छोटी टेबल में विभाजित करने और उन तालिकाओं के अंदर कुछ पंक्तियों और स्तंभों को हटाने की आवश्यकता थी, लेकिन अंत में यह काम करता था। आपको बहुत बहुत धन्यवाद। – Atheuz

+0

reclosedev: मैंने एक विशिष्ट मामले को संभालने के तरीके पर एक समस्या के साथ, मेरी मुख्य पोस्ट संपादित की। यदि आप इसका उत्तर दे सकते हैं तो मैं आभारी रहूंगा। – Atheuz

+0

@Atheuz, अद्यतन उत्तर देखें। पहला कार्य वास्तव में गलत था :(, लेकिन यह काम करना चाहिए। – reclosedev

1

जो एक अजगर 3 और BeautifulSoup समाधान चाहते हैं के लिए,

def table_to_2d(table_tag): 
    rows = table_tag("tr") 
    cols = rows[0](["td", "th"]) 
    table = [[None] * len(cols) for _ in range(len(rows))] 
    for row_i, row in enumerate(rows): 
     for col_i, col in enumerate(row(["td", "th"])): 
      insert(table, row_i, col_i, col) 
    return table 


def insert(table, row, col, element): 
    if row >= len(table) or col >= len(table[row]): 
     return 
    if table[row][col] is None: 
     value = element.get_text() 
     table[row][col] = value 
     if element.has_attr("colspan"): 
      span = int(element["colspan"]) 
      for i in range(1, span): 
       table[row][col+i] = value 
     if element.has_attr("rowspan"): 
      span = int(element["rowspan"]) 
      for i in range(1, span): 
       table[row+i][col] = value 
    else: 
     insert(table, row, col + 1, element) 

उपयोग:

soup = BeautifulSoup('<table><tr><th>1</th><th>2</th><th>5</th></tr><tr><td rowspan="2">3</td><td colspan="2">4</td></tr><tr><td>6</td><td>7</td></tr></table>', 'html.parser') 
print(table_to_2d(soup.table)) 

यह नहीं अनुकूलित है। मैंने इसे अपनी एक बार की लिपि के लिए लिखा था।

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