使用Python BeautifulSoup提取HTML表

时间:2015-05-10 17:23:04

标签: python html beautifulsoup

我正在尝试从网页中提取表格。下面是使用beautifulsoup的HTML和Python代码。下面的代码总是对我有用,但在这种情况下,我得到了空白。提前谢谢。

<table>
<thead>
<tr>
<th>Period Ending:</th>
<th class="TalignL">Trend</th>
<th>9/27/2014</th>
<th>9/28/2013</th>
<th>9/29/2012</th>
<th>9/24/2011</th>
</tr>
</thead>
<tr>
<th bgcolor="#E6E6E6">Total Revenue</th>
<td class="td_genTable"><table border="0" align="center" width="*" cellspacing="0" cellpadding="0"><tr><td align="bottom"><table border="0" height="100%" cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" border="0"><tr><td height="15" bgcolor="#47C3D3" width="6"></td><td height="15" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="1" colspan="2" bgcolor="#D1D1D1"></td></tr></table></td><td><table cellspacing="0" cellpadding="0" border="0"><tr><td height="1" bgcolor="#FFFFFF" width="6"></td><td height="1" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="14" bgcolor="#47C3D3" width="6"></td><td height="14" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="1" colspan="2" bgcolor="#D1D1D1"></td></tr></table></td><td><table cellspacing="0" cellpadding="0" border="0"><tr><td height="2" bgcolor="#FFFFFF" width="6"></td><td height="2" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="13" bgcolor="#47C3D3" width="6"></td><td height="13" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="1" colspan="2" bgcolor="#D1D1D1"></td></tr></table></td><td><table cellspacing="0" cellpadding="0" border="0"><tr><td height="7" bgcolor="#FFFFFF" width="6"></td><td height="7" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="8" bgcolor="#47C3D3" width="6"></td><td height="8" bgcolor="#FFFFFF" width="1px"></td></tr><tr><td height="1" colspan="1" bgcolor="#D1D1D1"></td></tr></table></td></tr></table></td></tr></table></td>
<td>$182,795,000</td>
<td>$170,910,000</td>
<td>$156,508,000</td>
<td>$108,249,000</td>
    rows = table.findAll('tr')

    for row in rows:
        cols = row.findAll('td')
        col1 = [ele.text.strip().replace(',','') for ele in cols]

        account = col1[0:1]
        period1 = col1[2:3]
        period2 = col1[3:4]
        period3 = col1[4:5]

        record = (stock, account,period1,period3,period3)
        print record

2 个答案:

答案 0 :(得分:2)

添加@abarnert指出的内容。我会得到所有td个元素,文字以$开头:

for row in soup.table.find_all('tr', recursive=False):
    record = [td.text.replace(",", "") for td in row.find_all("td", text=lambda x: x and x.startswith("$"))]
    print record

对于您提供的输入,它会打印:

[u'$182795000', u'$170910000', u'$156508000', u'$108249000']

你可以&#34;解包&#34;分成变量:

account, period1, period2, period3 = record

请注意,我明确传递recursive=False以避免在树中更深入,只获得tr元素的直接table子项。

答案 1 :(得分:1)

你的第一个问题是find_all(或findAll,这只是同一件事的弃用同义词)不只是找到表中的行,而是找到表中的行及其中的每个子表。你几乎肯定不想迭代这两种行,并在每一行上运行相同的代码。如果您不希望这样,就像the recursive argument文档所说,传递recursive=False

所以,现在你只回来一行了。如果你执行row.find_all('td'),那将会再次遇到同样的问题 - 你会找到这一行的所有列,以及其中一列中每个子表中每行的所有列。同样,这不是你想要的,所以使用recursive=False

现在你只回来了5列。第一个只是一张大桌子,里面有一堆空单元;另一方面,其他人有美元价值,这似乎是你想要的。

所以,只需在两个调用中添加recursive=False,并将stock设置为某些内容(我不知道代码中应该包含哪些内容,但如果没有它,您显然会去得到一个NameError):

stock = 'spam'

rows = table.find_all('tr', recursive=False)

for row in rows:
    cols = row.findAll('td', recursive=False)
    col1 = [ele.text.strip().replace(',','') for ele in cols]

    account = col1[0:1]
    period1 = col1[2:3]
    period2 = col1[3:4]
    period3 = col1[4:5]

    record = (stock, account,period1,period3,period3)

    print record

这将打印:

('spam', [''], ['$170910000'], ['$108249000'], ['$108249000'])

我不确定为什么你曾两次使用period3并且从未使用过period2,为什么你完全跳过第1列,或者为什么要切换单元素列表而不是仅仅索引值,无论如何,这似乎是你想要做的。

作为旁注,如果你真的想要将列表分成5个值,而不是跳过4个1元素列表中的一个值,你可以写:

account, whatever, period1, period2, period3 = col