在python中使用Beautifulsoop4解析内部td标记

时间:2016-07-17 01:37:08

标签: python regex beautifulsoup

我正在开发一个小项目,并且我很难使用bs4从html代码解析所需的行。

HTML:

 <div id="results_box">
 <table class="genTbl closedTbl historicalTbl" id="curr_table">
    <thead>
        <tr>
            <th class="first left noWrap">Date</th>
            <th class="noWrap">Price</th>
            <th class="noWrap">Open</th>
            <th class="noWrap">High</th>
            <th class="noWrap">Low</th>
            <th class="noWrap">Vol.</th>            <th class="noWrap">Change %</th>
        </tr>
    </thead>
    <tbody>
            <tr>
            <td class="first left bold noWrap">Jul 15, 2016</td>
            <td class="redFont">98.78</td>
            <td>99.02</td>
            <td>99.30</td>
            <td>98.51</td>
            <td>30.14M</td>            <td class="bold redFont">-0.01%</td>
        </tr>
                <tr>
            <td class="first left bold noWrap">Jul 14, 2016</td>
            <td class="greenFont">98.79</td>
            <td>97.39</td>
            <td>98.99</td>
            <td>97.32</td>
            <td>38.92M</td>            <td class="bold greenFont">1.98%</td>
         </tr> 

我需要从这两行中提取-0.01%和1.98%

<td class="bold redFont">-0.01%</td>
<td class="bold greenFont">1.98%</td>

我用过

txt = parsed_html.find("table", {"id":"curr_table"}).find_all("td", {"class":re.compile('bold .*Font')})
for row in txt:
  L.append(row.text)
print(L)

但我得到一个空列表。任何解决方案或其他建议?

1 个答案:

答案 0 :(得分:2)

您当前的方法不起作用的原因是classBeautifulSoup中的特殊多值属性,并且正则表达式不会应用于完整属性,但对于单个类,这个线程应该更详细地解释它:

您实际上可以避免检查类值,而只需抓取文本末尾td的{​​{1}}元素:

%

我实际上会使用pandas将格式良好的表解析为数据帧,这非常方便。 table = parsed_html.find("table", {"id":"curr_table"}) for td in table.find_all("td", text=lambda text: text and text.endswith('%')): print(td.get_text()) 提供extensive documentation来帮助您了解如何使用数据框:

pandas

打印:

import pandas as pd

data = """
 <table class="genTbl closedTbl historicalTbl" id="curr_table">
    <thead>
        <tr>
            <th class="first left noWrap">Date</th>
            <th class="noWrap">Price</th>
            <th class="noWrap">Open</th>
            <th class="noWrap">High</th>
            <th class="noWrap">Low</th>
            <th class="noWrap">Vol.</th>            <th class="noWrap">Change %</th>
        </tr>
    </thead>
    <tbody>
            <tr>
            <td class="first left bold noWrap">Jul 15, 2016</td>
            <td class="redFont">98.78</td>
            <td>99.02</td>
            <td>99.30</td>
            <td>98.51</td>
            <td>30.14M</td>            <td class="bold redFont">-0.01%</td>
        </tr>
                <tr>
            <td class="first left bold noWrap">Jul 14, 2016</td>
            <td class="greenFont">98.79</td>
            <td>97.39</td>
            <td>98.99</td>
            <td>97.32</td>
            <td>38.92M</td>            <td class="bold greenFont">1.98%</td>
         </tr>
    </tbody>
</table>
"""

df = pd.read_html(data)[0]
print(df)

print("----")
print(df['Change %'].tolist())