2015-05-10 589 views
1

我想从网页中提取表格。下面是使用beautifulsoup的HTML和Python代码。下面的代码总是为我工作,但在这种情况下,我变得空白。提前致谢。使用Python提取HTML表格BeautifulSoup

<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 
+1

你第一个非标题行的第一列包含一个充满空单元格的表格,其中没有文本。你的代码正确地发现没有文字。我不确定你想要它做什么。 – abarnert

+0

同时,您为什么使用不推荐的名称'findAll'?您是否从针对BS3编写的示例代码学习,而不是从BS4的更新示例或文档中学习? – abarnert

+0

最后,['find_all'](http://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all)(或'findAll')搜索_all后代_,而不仅仅是顶级子代。因此,除非您想遍历外部表的行和嵌入在该表的列中的每个子表的行并将它们对待,否则您不应该在此处使用它。 – abarnert

回答

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'] 

,你可以“解压缩”成独立的变量:

account, period1, period2, period3 = record 

请注意,我明确地通过recursive=False,以避免深入树中,只得到tr孩子的table元素。

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列,或者你为什么要切分1元素列表而不是索引值,但无论如何,这似乎就是你想要做的。


作为一个侧面说明,如果你真的想打出来的清单到5个值,而不是进入4跳过的一个值1元的列表,你可以写:

account, whatever, period1, period2, period3 = col 
+1

@alecxe:要编写书籍,你必须能够编辑东西。我的第一章是1300页。 (这可能适用于小说,但Tristam Shandy已经在250年前写过了......) – abarnert

+0

这个工作!谢谢。你是对的。我正在使用股票作为变量来循环多个股票。再次感谢。 –

相关问题