在python中使用colspan和beautifulsou解析表

在python中使用colspan和beautifulsou解析表,python,html,css,beautifulsoup,Python,Html,Css,Beautifulsoup,我的html如下所示: <table cellspacing="0" class="tbOdpis" width="100%"> <td class="csTytul" colspan="100" width="100%">Rubryka 0.1 - Informacje podstawowe</td><td class="csTBreak" colspan="100" width="100%">

我的html如下所示:

<table cellspacing="0" class="tbOdpis" width="100%">

<td class="csTytul" colspan="100" width="100%">Rubryka 0.1 - Informacje podstawowe</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCOpis" colspan="55" width="55%">Treść pola</td><td class="csBOpis" colspan="4" width="4%">1.</td><td class="csBOpis" colspan="41" width="41%">Numer księgi</td><td class="csBDDane" colspan="55" width="55%">xxx / 000xxxxxx / x</td><td class="csBreak" colspan="100" width="100%">
                        -
                        </td><td class="csOpis" colspan="4" rowspan="6" style="vertical-align:top;" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Oznaczenie wydziału</td><td class="csOpis" colspan="55" width="55%">---</td><td class="csOpis" colspan="41" width="41%">A: nazwa sądu</td><td class="csBDane" colspan="55" width="55%">xxxxxxxxxxxxxxx</td><td class="csOpis" colspan="41" width="41%">B: siedziba sądu</td><td class="csBDane" colspan="55" width="55%">xxxx</td><td class="csOpis" colspan="41" width="41%">C: kod wydziału</td><td class="csBDane" colspan="55" width="55%">xxxx</td><td class="csOpis" colspan="41" width="41%">D: numer wydziału</td><td class="csBDane" colspan="55" width="55%">III</td><td class="csOpis" colspan="41" width="41%">E: nazwa wydziału</td><td class="csBDane" colspan="55" width="55%">WYDZIAŁ KSIĄG WIECZYSTYCH</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">3.</td><td class="csOpis" colspan="41" width="41%">Typ księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">LOKAL STANOWIĄCY ODRĘBNĄ NIERUCHOMOŚĆ</td>
<td class="csEmptyLine" colspan="100" width="100%"></td><td class="csTytul" colspan="100" width="100%">Rubryka 0.2 - Dane o założeniu księgi wieczystej</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">1.</td><td class="csOpis" colspan="41" width="41%">Stan w czasie założenia</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">ZAŁOŻENIE KSIĘGI WIECZYSTEJ W WYNIKU WYODRĘBNIENIA LOKALU</td><td class="csOpis" colspan="4" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Chwila zapisania księgi</td><td class="csOpis" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td><td class="csOpis" colspan="4" width="4%">3.</td><td class="csOpis" colspan="41" width="41%">Chwila ujawnienia księgi</td><td class="csOpis" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td><td class="csOpis" colspan="4" width="4%">4.</td><td class="csOpis" colspan="41" width="41%">Data założenia dotychczasowej księgi wieczystej</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td>
<td class="csEmptyLine" colspan="100" width="100%"></td><td class="csTytul" colspan="100" width="100%">Rubryka 0.3 - Dane o zamknięciu księgi wieczystej</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">1.</td><td class="csOpis" colspan="41" width="41%">Chwila zamknięcia księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">---</td><td class="csOpis" colspan="4" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Podstawa zamknięcia księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">---</td>
</table>

def table_to_2d(table_tag):
    rowspans = []  # track pending rowspans
    rows = table_tag.find_all('tr')
    colcount = 0
    for r, row in enumerate(rows):
        cells = row.find_all(['td', 'th'], recursive=False)

        colcount = max(
            colcount,
            sum(int(c.get('colspan', 1)) or 1 for c in cells[:-1]) + len(cells[-1:]) + len(rowspans))

        rowspans += [int(c.get('rowspan', 1)) or len(rows) - r for c in cells]
        rowspans = [s - 1 for s in rowspans if s > 1]

    table = [[None] * colcount for row in rows]

    rowspans = {}  # track pending rowspans, column number mapping to count
    for row, row_elem in enumerate(rows):
        span_offset = 0  # how many columns are skipped due to row and colspans 
        for col, cell in enumerate(row_elem.find_all(['td', 'th'], recursive=False)):

            col += span_offset
            while rowspans.get(col, 0):
                span_offset += 1
                col += 1

            rowspan = rowspans[col] = int(cell.get('rowspan', 1)) or len(rows) - row
            colspan = int(cell.get('colspan', 1)) or colcount - col

            span_offset += colspan - 1
            value = cell.get_text()
            for drow, dcol in product(range(rowspan), range(colspan)):
                try:
                    table[row + drow][col + dcol] = value
                    rowspans[col + dcol] = rowspan
                except IndexError:
                    pass

        rowspans = {c: s - 1 for c, s in rowspans.items() if s > 1}

    return table
一切都很顺利。现在开发者已经改变了上面显示的形状,意思是没有行标记

如何改进代码以正确解析新形状?

帮助

pd.read_html(r"pathtohtmlfile",flavor='bs4')

这已经以正确的方式解析了我的表

只是为了将它留在这里,没有熊猫的东西:

data = '''<table cellspacing="0" class="tbOdpis" width="100%">

<td class="csTytul" colspan="100" width="100%">Rubryka 0.1 - Informacje podstawowe</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCOpis" colspan="55" width="55%">Treść pola</td><td class="csBOpis" colspan="4" width="4%">1.</td><td class="csBOpis" colspan="41" width="41%">Numer księgi</td><td class="csBDDane" colspan="55" width="55%">xxx / 000xxxxxx / x</td><td class="csBreak" colspan="100" width="100%">
                        -
                        </td><td class="csOpis" colspan="4" rowspan="6" style="vertical-align:top;" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Oznaczenie wydziału</td><td class="csOpis" colspan="55" width="55%">---</td><td class="csOpis" colspan="41" width="41%">A: nazwa sądu</td><td class="csBDane" colspan="55" width="55%">xxxxxxxxxxxxxxx</td><td class="csOpis" colspan="41" width="41%">B: siedziba sądu</td><td class="csBDane" colspan="55" width="55%">xxxx</td><td class="csOpis" colspan="41" width="41%">C: kod wydziału</td><td class="csBDane" colspan="55" width="55%">xxxx</td><td class="csOpis" colspan="41" width="41%">D: numer wydziału</td><td class="csBDane" colspan="55" width="55%">III</td><td class="csOpis" colspan="41" width="41%">E: nazwa wydziału</td><td class="csBDane" colspan="55" width="55%">WYDZIAŁ KSIĄG WIECZYSTYCH</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">3.</td><td class="csOpis" colspan="41" width="41%">Typ księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">LOKAL STANOWIĄCY ODRĘBNĄ NIERUCHOMOŚĆ</td>
<td class="csEmptyLine" colspan="100" width="100%"></td><td class="csTytul" colspan="100" width="100%">Rubryka 0.2 - Dane o założeniu księgi wieczystej</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">1.</td><td class="csOpis" colspan="41" width="41%">Stan w czasie założenia</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">ZAŁOŻENIE KSIĘGI WIECZYSTEJ W WYNIKU WYODRĘBNIENIA LOKALU</td><td class="csOpis" colspan="4" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Chwila zapisania księgi</td><td class="csOpis" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td><td class="csOpis" colspan="4" width="4%">3.</td><td class="csOpis" colspan="41" width="41%">Chwila ujawnienia księgi</td><td class="csOpis" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td><td class="csOpis" colspan="4" width="4%">4.</td><td class="csOpis" colspan="41" width="41%">Data założenia dotychczasowej księgi wieczystej</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">xxxxx xxxxx xxxxx</td>
<td class="csEmptyLine" colspan="100" width="100%"></td><td class="csTytul" colspan="100" width="100%">Rubryka 0.3 - Dane o zamknięciu księgi wieczystej</td><td class="csTBreak" colspan="100" width="100%">
                        -
                        </td><td class="csCOpis" colspan="45" width="45%">Numer i nazwa pola</td><td class="csCMOpis" colspan="10" width="10%">Indeks zmiany</td><td class="csCOpis" colspan="45" width="45%">Treść pola</td><td class="csOpis" colspan="4" width="4%">1.</td><td class="csOpis" colspan="41" width="41%">Chwila zamknięcia księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">---</td><td class="csOpis" colspan="4" width="4%">2.</td><td class="csOpis" colspan="41" width="41%">Podstawa zamknięcia księgi</td><td class="csDane" colspan="10" width="10%">---</td><td class="csDane" colspan="45" width="45%">---</td>
</table>'''

from bs4 import BeautifulSoup
from itertools import accumulate, groupby
from pprint import pprint

soup = BeautifulSoup(data, 'lxml')


for td in soup.select('td[rowspan]'):
    num = int(td['rowspan'])
    del td['rowspan']
    t = td
    for i in range(0, num-1):
        new_td = soup.new_tag('td', attrs=td.attrs)
        new_td.append(td.text)
        t = t.find_next(lambda x: x['colspan'] == '55')
        t.insert_after(new_td)

lst = soup.select('td')

s = '<table width=100% border=2>\n'
a = accumulate(int(td['colspan']) for td in lst)
for v, g in groupby(lst, lambda k, i=iter((next(a)-1) // 100 for _ in lst): next(i)):
    s += '<tr>\n'
    s += '\n'.join(str(t) for t in g)
    s += '</tr>\n'
s += '</table>'

soup = BeautifulSoup(s, 'lxml')

data =  []
for tr in soup.select('tr'):
    row = [td.text.strip() for td in tr.select('td') if td.text.strip() not in ('', '-')]
    if row:
        data.append(row)

for row in data:
    for i, td in enumerate(row):
        if i == 0:
            print('{: <4}'.format(td), end='')
        else:
            print('{: <50}'.format(td), end='')
    print()

使用熊猫的
read_html()
非常感谢。我只需在“bs4”上添加味道,我正要给你们发一条信息,让你们试试:-)
Rubryka 0.1 - Informacje podstawowe
Numer i nazwa polaTreść pola                                        
1.  Numer księgi                                      xxx / 000xxxxxx / x                               
2.  Oznaczenie wydziału                               ---                                               
2.  A: nazwa sądu                                     xxxxxxxxxxxxxxx                                   
2.  B: siedziba sądu                                  xxxx                                              
2.  C: kod wydziału                                   xxxx                                              
2.  D: numer wydziału                                 III                                               
2.  E: nazwa wydziału                                 WYDZIAŁ KSIĄG WIECZYSTYCH                         
Numer i nazwa polaIndeks zmiany                                     Treść pola                                        
3.  Typ księgi                                        ---                                               LOKAL STANOWIĄCY ODRĘBNĄ NIERUCHOMOŚĆ             
Rubryka 0.2 - Dane o założeniu księgi wieczystej
Numer i nazwa polaIndeks zmiany                                     Treść pola                                        
1.  Stan w czasie założenia                           ---                                               ZAŁOŻENIE KSIĘGI WIECZYSTEJ W WYNIKU WYODRĘBNIENIA LOKALU
2.  Chwila zapisania księgi                           ---                                               xxxxx xxxxx xxxxx                                 
3.  Chwila ujawnienia księgi                          ---                                               xxxxx xxxxx xxxxx                                 
4.  Data założenia dotychczasowej księgi wieczystej   ---                                               xxxxx xxxxx xxxxx                                 
Rubryka 0.3 - Dane o zamknięciu księgi wieczystej
Numer i nazwa polaIndeks zmiany                                     Treść pola                                        
1.  Chwila zamknięcia księgi                          ---                                               ---                                               
2.  Podstawa zamknięcia księgi                        ---                                               ---