【发布时间】:2012-08-14 05:10:18
【问题描述】:
我正在努力使用 Beautiful Soup 将一些易碎的 HTML 表格解析为列表。有问题的表缺少 标签。
使用以下代码(不是我正在解析的真实表格,但功能相似):
import bs4
test = "<table> <tr><td>1<td>2<td>3</tr> <tr><td>1<td>2<td>3</tr> </table>"
def walk_table2(text):
"Take an HTML table and spit out a list of lists (of entries in a row)."
soup = bs4.BeautifulSoup(text)
return [[x for x in row.findAll('td')] for row in soup.findAll('tr')]
print walk_table2(test)
给我:
[[<td>1<td>2<td>3</td></td></td>, <td>2<td>3</td></td>, <td>3</td>], [<td>4<td>5<td>6</td></td></td>, <td>5<td>6</td></td>, <td>6</td>]]
而不是预期:
[[<td>1</td>, <td>2</td>, <td>3</td>], [<td>1</td>, <td>2</td>, <td>3</td>]]
Beautiful Soup 使用的 lxml 解析器似乎决定在 的下一个实例之前添加 标记,而不是在
此时,我想知道是否有一个好的选项可以让解析器将结束 td 标记放置在正确的位置,或者在将字符串放入之前使用正则表达式手动放置它们是否更容易BeautifulSoup...有什么想法吗?提前致谢!
【问题讨论】:
-
美汤的行为似乎完全理性。它找到 `' 标记并得出结论,表格行内的任何打开标记都需要关闭。虽然它是完全合理的,但它也可能是错误的。
-
我不知道 Beautiful Soup 做了什么,但根据 HTML 5 的规则,解析器应该处于“单元格中”插入模式,它指定在打开新的之前关闭第一个 td .在 HTML 4 中,根据 SGML 解析规则,
TD有一个可选的结束标记,并且不能包含嵌套的TD,因此在遇到新的开始标记时应该关闭:<!ELEMENT (TH|TD) - O (%flow;)* -- table header cell, table data cell-->- 所以这种行为在客观上是错误的任何一个标准,不能被称为“完全合理”:此代码是合法的 HTML,并且毫无疑问是一个结构合理的表格。
标签: python html beautifulsoup