当表缺少thead元素

时间:2017-07-25 00:20:56

标签: python beautifulsoup lxml

当该表没有<thead>个元素时,我想检测HTML表的标题。 (MediaWiki,它驱动维基百科,does not support <thead> elements。)我想在BeautifulSoup和lxml中使用python执行此操作。假设我已经拥有一个table对象,我想摆脱一个thead对象,一个tbody对象和一个tfoot对象。

目前,当parse_thead标记存在时,<thead>执行以下操作:

  • 在BeautifulSoup中,我获得了doc.find_all('table')的表格对象,我可以使用table.find_all('thead')
  • 在lxml中,我在doc.xpath()的xpath_expr上获得了//table的表对象,我可以使用table.xpath('.//thead')

parse_tbody以及parse_tfoot的工作方式相同。 (我没有编写此代码,我对BS或lxml没有经验。)但是,如果没有<thead>parse_thead将不返回任何内容,parse_tbody将标题和正文一起返回。

我在下面添加wikitable instance作为示例。它缺少<thead><tbody>。相反,所有行,标题或不包含在<tr>...</tr>中,但标题行包含<th>元素,正文行包含<td>个元素。如果没有<thead>,那么识别标题的正确标准似乎是“从头开始,将行放入标题,直到找到具有不是<th>的元素的行。”

我很感激有关如何撰写parse_theadparse_tbody的建议。没有太多经验,我认为我可以

  • 潜入表对象并在解析之前手动插入theadtbody标签(这看起来不错,因为我不需要更改任何其他识别带{{1}的表的代码}),或者
  • 更改<thead>parse_thead以识别仅包含parse_tbody元素的表格行。 (无论哪种方式,似乎我都需要以这种方式检测头身边界。)

我不知道如何做其中任何一件事,我很欣赏有关哪种替代方案更明智以及我如何去做的建议。

(编辑:no header rowsmultiple header rows的示例。我不能假设它只有一个标题行。)

<th>

2 个答案:

答案 0 :(得分:1)

您应该验证tr标记是否包含您想要的th子项,candidate.th如果None内没有th,则会candidate返回possibleHeaders = soup.find("table").findAll("tr") Headers = [] for candidate in possibleHeaders: if candidate.th: Headers.append(candidate) {1}}:

let pinfo = NSPrintInfo.shared()
pinfo.orientation = .landscape
pinfo.bottomMargin = 0.0
pinfo.topMargin = 0.0
pinfo.leftMargin = 0.0
pinfo.rightMargin = 0.0
drawing!.print(self)

答案 1 :(得分:1)

如果表格不包含<th>标记,我们可以使用<thead>标记来检测标题。如果一行的所有列都是<th>标记,那么我们可以假设它是标题。基于此,我创建了一个标识标题和正文的函数。

BeautifulSoup的代码:

def parse_table(table): 
    head_body = {'head':[], 'body':[]}
    for tr in table.select('tr'): 
        if all(t.name == 'th' for t in tr.find_all(recursive=False)): 
            head_body['head'] += [tr]
        else: 
            head_body['body'] += [tr]
    return head_body 

lxml的代码:

def parse_table(table): 
    head_body = {'head':[], 'body':[]}
    for tr in table.cssselect('tr'): 
        if all(t.tag == 'th' for t in tr.getchildren()): 
            head_body['head'] += [tr]
        else: 
            head_body['body'] += [tr]
    return head_body 

table参数是Beautiful Soup Tag对象或lxml Element对象。 head_body是一个字典,其中包含两个<tr>标记列表,标题和正文行。

用法示例:

html = '<table><tr><th>heade</th></tr><tr><td>body</td></tr></table>'
soup = BeautifulSoup(html, 'html.parser')
table = soup.find('table')
table_rows = parse_table(table)

print(table_rows)
#{'head': [<tr><th>header</th></tr>], 'body': [<tr><td>body</td></tr>]}