2016-08-14 61 views
0

我有一个使用BeautifulSoup和Python在线抓取数据的自我项目,我认为历史股票数据对我来说是一个很好的练习。我查看了源代码here以分析如何使用BeautifulSoup的select()或findall()来解析表中的部分数据。这里是我使用的代码,但是它解析了表以外的其他东西。使用BeautifulSoup解析数据表的一部分

soup = bs4.BeautifulSoup(res.text, 'lxml') table = soup.findAll('td', {'class':'yfnc_tabledata1'}) print table

我的问题:如何我解析只有2行显示从表中数据的2天呢?

这里是一个具有2天的历史数据表:

<table class="yfnc_datamodoutline1" width="100%" cellpadding="0" cellspacing="0" border="0"> 

<tr valign="top"> 
<td> 

<table border="0" cellpadding="2" cellspacing="1" width="100%"> 
<tr> 
<th scope="col" class="yfnc_tablehead1" align="right" width="16%">Date</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="12%">Open</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="12%">High</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="12%">Low</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="12%">close</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="16%">Volume</th> 
<th scope="col" class="yfnc_tablehead1" align="right" width="15%">Adj Close*</th> 
</tr> 
<tr> 
<td class="yfnc_tabledata1" nowrap align="right">12 Aug 2016</td> 
<td class="yfnc_tabledata1" align="right">107.78</td> 
<td class="yfnc_tabledata1" align="right">108.44</td> 
<td class="yfnc_tabledata1" align="right">107.78</td> 
<td class="yfnc_tabledata1" align="right">108.18</td> 
<td class="yfnc_tabledata1" align="right">18,612,300</td> 
<td class="yfnc_tabledata1" align="right">108.18</td> 
</tr> 
<tr> 
<td class="yfnc_tabledata1" nowrap align="right">11 Aug 2016</td> 
<td class="yfnc_tabledata1" align="right">108.52</td> 
<td class="yfnc_tabledata1" align="right">108.93</td> 
<td class="yfnc_tabledata1" align="right">107.85</td> 
<td class="yfnc_tabledata1" align="right">107.93</td> 
<td class="yfnc_tabledata1" align="right">27,484,500</td> 
<td class="yfnc_tabledata1" align="right">107.93</td> 
</tr> 
<tr> 
<td class="yfnc_tabledata1" colspan="7" align="center"> 
* <small>Close price adjusted for dividends and splits.</small> 
</td> 
</tr> 
</table> 

</td> 
</tr> 
</table> 

我只需要从上述特定2行数据:

<tr> 
<td class="yfnc_tabledata1" nowrap align="right">12 Aug 2016</td> 
<td class="yfnc_tabledata1" align="right">107.78</td> 
<td class="yfnc_tabledata1" align="right">108.44</td> 
<td class="yfnc_tabledata1" align="right">107.78</td> 
<td class="yfnc_tabledata1" align="right">108.18</td> 
<td class="yfnc_tabledata1" align="right">18,612,300</td> 
<td class="yfnc_tabledata1" align="right">108.18</td> 
</tr> 
<tr> 
<td class="yfnc_tabledata1" nowrap align="right">11 Aug 2016</td> 
<td class="yfnc_tabledata1" align="right">108.52</td> 
<td class="yfnc_tabledata1" align="right">108.93</td> 
<td class="yfnc_tabledata1" align="right">107.85</td> 
<td class="yfnc_tabledata1" align="right">107.93</td> 
<td class="yfnc_tabledata1" align="right">27,484,500</td> 
<td class="yfnc_tabledata1" align="right">107.93</td> 
</tr> 
+1

我看不出嵌套级别如何改变。使用'find()'获取表格后,您可以访问它的子元素,而不必担心嵌套。你真正的问题是什么?你在找桌子时有困难吗? –

+0

我不仅解析表格,还解析网页的其他部分。 –

回答

0

您可以选择所有的行来自嵌套表yfnc_datamodoutline1表和索引前两个:

soup = BeautifulSoup(html) 
table_rows = soup.select("table.yfnc_datamodoutline1 table tr + tr") 
row1, row2 = table_rows[0:2] 

print(row1) 
print(row2) 

这将使你:

<tr> 
<td align="right" class="yfnc_tabledata1" nowrap="">12 Aug 2016</td> 
<td align="right" class="yfnc_tabledata1">107.78</td> 
<td align="right" class="yfnc_tabledata1">108.44</td> 
<td align="right" class="yfnc_tabledata1">107.78</td> 
<td align="right" class="yfnc_tabledata1">108.18</td> 
<td align="right" class="yfnc_tabledata1">18,612,300</td> 
<td align="right" class="yfnc_tabledata1">108.18</td> 
</tr> 
<tr> 
<td align="right" class="yfnc_tabledata1" nowrap="">11 Aug 2016</td> 
<td align="right" class="yfnc_tabledata1">108.52</td> 
<td align="right" class="yfnc_tabledata1">108.93</td> 
<td align="right" class="yfnc_tabledata1">107.85</td> 
<td align="right" class="yfnc_tabledata1">107.93</td> 
<td align="right" class="yfnc_tabledata1">27,484,500</td> 
<td align="right" class="yfnc_tabledata1">107.93</td> 
</tr> 

要获得TD数据只是提取每个TD文本:

print([td.text for td in row1.find_all("td")]) 
print([td.text for td in row2.find_all("td")]) 

这将使你:

[u'12 Aug 2016', u'107.78', u'108.44', u'107.78', u'108.18', u'18,612,300', u'108.18'] 
[u'11 Aug 2016', u'108.52', u'108.93', u'107.85', u'107.93', u'27,484,500', u'107.93'] 

table.yfnc_datamodoutline1表tr + tr选择内部表中跳过第一个标题行的所有行。

+0

table.yfnc_datamodoutline1表tr + tr解析2行。当需要解析不同数量的数据行时该怎么办? –

+0

@LEDFantom,我不明白你'mean.table.yfnc_datamodoutline1 table tr + tr parses'解析了所有不包含第一行的行 –