将html表转换为字典而不会丢失结构

时间:2015-04-01 16:15:41

标签: python html beautifulsoup html-parsing

我是python(和编程)的新手并且第一次使用BeautifulSoup

我试图找到解析html中表格内容并转换为字典的最佳方法 - 最好是以最不易碎的方式。

以下是我尝试解析的HTML示例(我已经为我试图提取的文字设置了关键值数字。)

<div class="tablename">
<table border="0" cellpadding="0" cellspacing="0" style="border: 1px solid #dddddd;  border-collapse: collapse; font-family: Arial, Helvetica, sans-serif; font-size: 14px; margin: 0; padding: 0; width: 100%">
<thead>
<tr>
<th colspan="4" style="background-color: #000; border: 1px solid #616161; color: #ffffff; font-size: 14px; font-weight: bold; line-height: 20px; padding: 14px 20px 12px 20px; text-align: left">Some text not needed</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 20px"> </td>
<td style="border-bottom: 1px solid #dddddd; color: #666666; font-size: 14px; line-height: 20px; padding: 11px 20px 10px 0; text-align: left; width: 42.5%; vertical-align: middle">Key 1</td>
<td style="border-bottom: 1px solid #dddddd; color: #000; font-size: 14px; line-height: 20px; padding: 11px 0 10px 0; text-align: left; vertical-align: middle">Value 1</td>
<td style="width: 20px"> </td>
</tr>
<tr>
<td> </td>
<td style="border-bottom: 1px solid #dddddd; color: #666666; font-size: 14px; line-height: 20px; padding: 11px 20px 10px 0; text-align: left; vertical-align: middle">Key 2</td>
<td style="border-bottom: 1px solid #dddddd; color: #000; font-size: 14px; line-height: 20px; padding: 11px 0 10px 0; text-align: left; vertical-align: middle">Value 2</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td style="border-bottom: 1px solid #dddddd; color: #666666; font-size: 14px; line-height: 20px; padding: 11px 20px 10px 0; text-align: left; vertical-align: middle">Key 3</td>
<td style="border-bottom: 1px solid #dddddd; color: #000; font-size: 14px; line-height: 20px; padding: 11px 0 10px 0; text-align: left; vertical-align: middle">Value 3</td>
<td> </td>
</tr>
<tr>

我使用的代码:

import requests
from bs4 import BeautifulSoup

html = requests.get('https://examplewebaddress.com')
soup = BeautifulSoup(html.text)
print(soup.tbody.text)

然后我可以遍历soup.tbody.text字符串并将其拆分为键值对。但这似乎并不是一个好方法,我似乎通过将其转换为字符串然后再将其重新构建为字典来丢失表的结构。

是否有更直接的方法将BeautifulSoup(或更合适的东西)解析成一个字典,然后我可以使用它?

1 个答案:

答案 0 :(得分:2)

想法是迭代表行,并为每一行提取第二个和第三个单元格的文本,它们代表键和未来字典的值:

soup = BeautifulSoup(html.text)

result = dict([[item.get_text(strip=True) for item in row.find_all('td')[1:3]]
               for row in soup.select("div.tablename table tr")[1:]])

print result

对于提供的样本数据,它会打印:

{u'Key 1': u'Value 1', u'Key 2': u'Value 2', u'Key 3': u'Value 3'}

div.tablename table tr是一个CSS selector,可与tr元素下table元素div以及class="tablename"作为父元素的所有select元素相匹配。我们正在对[1:]({{1}})的结果进行切片以跳过第一个标题行。