如何使用BeautifulSoup成对提取表数据?

时间:2011-11-15 16:37:52

标签: loops beautifulsoup python

我的数据样本:

<table id = "history">
<tr class = "printCol">
<td class="name">Google</td><td class="date">07/11/2001</td><td class="state">
<span>CA</span>
</td>
</tr>
<tr class = "printCol">
<td class="name">Apple</td><td class="date">27/08/2001</td>
</tr>
<tr class = "printCol">
<td class="name">Microsoft</td><td class="date">01/11/1991</td>
</tr>
</table>

Beautifulsoup代码:

table = soup.find("table", id = "history")

rows = table.findAll('tr')
for tr in rows:
    cols = tr.findAll('td')
    for td in cols:
        print td.find(text=True)

MySQL存储的期望输出(列表):

['Google|07/11/2001|CA', 'Apple|27/08/2001', 'Microsoft|01/11/1991']

我有输出(很难将正确的日期与正确的公司联系起来):

Google
07/11/2001


Apple
27/08/2001
Microsoft
01/11/1991

我编写了一个函数来从每个 tr 中提取元素,但我认为在原始 for 循环中有一种更有效的方法。我想将它们作为数据对存储在列表中。思考?

2 个答案:

答案 0 :(得分:17)

列表理解将使其更容易:

table = soup.find("table", id = "history")
rows = table.findAll('tr')
data = [[td.findChildren(text=True) for td in tr.findAll("td")] for tr in rows]
# data now contains:
[[u'Google', u'07/11/2001'],
 [u'Apple', u'27/08/2001'],
 [u'Microsoft', u'01/11/1991']]

# If the data may contain extraneous whitespace you can clean it up
# Additional processing could also be done - but once you hit much more
# complex than this later maintainers, yourself included, will thank you
# for using a series of for loops that call clearly named functions to perform
# the work.
data = [[u"".join(d).strip() for d in l] for l in data]

# If you want to store it joined as name | company
# then simply follow that up with:
data = [u"|".join(d) for d in data]

列表推导基本上是一个带有聚合的反向for循环:

[[td.findNext(text=True) for td in tr.findAll("td")] for tr in rows]

转换为 *

final_list = []
intermediate_list = []

for tr in rows:
    for td in tr.findAll("td")
        intermediate_list.append(td.findNext(text=True))

    final_list.append(intermediate_list)
    intermediate_list = []

data = final_list

* 粗略地说 - 我们遗漏了涉及发电机而不是构建中间列表的真棒,因为我无法正确添加发电机现在没有混乱的例子。

答案 1 :(得分:2)

如果您确切需要您所撰写的内容,那么这是肖恩答案的小变体,

table = soup.find("table", id = "history")

rows = table.findAll('tr')

data = ['|'.join([td.findNext(text=True) for td in tr.findAll("td")]) for tr in rows]
print data