谁能帮我理解这段代码(用lxml、python解析HTML表)?

谁能帮我理解这段代码(用lxml、python解析HTML表)?,html,parsing,python-3.x,lxml,lxml.html,Html,Parsing,Python 3.x,Lxml,Lxml.html,背景:我需要用python为具有不同列跨度和行跨度的html表编写一个html表解析器。经过一些研究,我无意中发现了这一点。它适用于没有古怪的colspan和rowspans的简单情况,但是我遇到了一个bug。代码假定,如果一个元素的colspan为3,则它属于三个不同的表头,而实际上它只属于colspan位于其中心的表头。这方面的一个例子可以在瑞典部分下的“打开倾斜表”中看到。代码错误地返回hans所有格-中性-第三人称阳性属于所有格-普通-第三人称阳性和所有格-复数-第三人称阳性,因为它的c

背景:我需要用python为具有不同列跨度和行跨度的html表编写一个html表解析器。经过一些研究,我无意中发现了这一点。它适用于没有古怪的colspan和rowspans的简单情况,但是我遇到了一个bug。代码假定,如果一个元素的colspan为3,则它属于三个不同的表头,而实际上它只属于colspan位于其中心的表头。这方面的一个例子可以在瑞典部分下的“打开倾斜表”中看到。代码错误地返回hans所有格-中性-第三人称阳性属于所有格-普通-第三人称阳性和所有格-复数-第三人称阳性,因为它的colspan为3。我尝试将检查添加到表_到_2d_dict中,如果colspan>1,它将创建一个计数器,并且如果计数器等于colspan//2+1,则仅将元素作为标头的一部分进行计数。这将返回范围1的中值,colspan+1是该元素应作为标头计数的表标头的值。但是,当我在下面代码中指定的位置实现此检查时,它不起作用。老实说,这可能是因为我不了解这段代码是如何工作的,所以

问题:有人能解释一下这段代码的作用以及为什么会出现上述故障吗?如果有人能实现一个修复,那就太好了,但现在我主要关心的是理解代码。谢谢

下面是我添加的带有注释的代码,以突出显示我理解的代码部分和我不理解的代码部分

#!/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(str))
    for row_i, row in enumerate(table.xpath('./tr')): #these double for loops iterate over each element in the table
        for col_i, col in enumerate(row.xpath('./td|./th')):
            colspan = int(col.get('colspan', 1)) #gets colspan attr of the element, if none assumes it's 1
            rowspan = int(col.get('rowspan', 1)) #gets rowspan attr of the element, if none assumes it's 1
            col_data = col.text_content() #gets raw text inside element

            #WHAT DOES THIS DO? :(
            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

#what does this do? :(
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)