在python中用Beautifulsoop4解析内部td标签

Posted

技术标签:

【中文标题】在python中用Beautifulsoop4解析内部td标签【英文标题】:Parsing inner td tag with Beautifulsoop4 in python 【发布时间】:2016-11-19 21:44:58 【问题描述】:

我正在做一个小项目,我很难使用 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】:

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

BeautifulSoup returns empty list when searching by compound class names

您实际上可以避免检查类值,而只需抓住文本末尾具有%td 元素:

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())

我实际上会使用pandas 将这个格式良好的表格解析为数据框,使用起来非常方便。 pandas 提供了一个 extensive documentation 来帮助您了解如何使用数据框:

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())

打印:

           Date  Price   Open   High    Low    Vol. Change %
0  Jul 15, 2016  98.78  99.02  99.30  98.51  30.14M   -0.01%
1  Jul 14, 2016  98.79  97.39  98.99  97.32  38.92M    1.98%
----
['-0.01%', '1.98%']

【讨论】:

以上是关于在python中用Beautifulsoop4解析内部td标签的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中用单引号或双引号提取字符串

在python中用正则表达式匹配任何字符和/或未定义的换行符

大侠们unity怎么在lua中用protobuf的

在颤动中用数组解析复杂的JSON

在 vb.net 中用 jrock 解析 json

IntelliJ IDEA 在 JPQL 中用“无法解析符号”突出显示 @Entity 类名