在Python中使用BeautifulSoup解析HTML

1 投票
2 回答
1796 浏览
提问于 2025-04-17 20:00

我正在用Python和BeautifulSoup来解析HTML,但总是无法得到我想要的结果。

这是我个人应用程序中的一个小模块,主要是一个网页登录部分,需要输入账号和密码。登录成功后,我需要解析一些信息,以便进行管理和处理。

登录后的HTML代码是:

<div class="widget_title clearfix">

        <h2>Account Balance</h2>

    </div>

    <div class="widget_body">

        <div class="widget_content">

            <table class="simple">

                <tr>

                    <td><a href="#" id="west1" title="Total earned daily">Daily Earnings</a></td>

                    <td style="text-align: right; width: 125px; color: #119911; font-weight: bold;">

                        150                         

                    </td>

                </tr>

                <tr>

                    <td><a href="#" id="west2" title="Total weekly earnings">Weekly Earnings</a></td>

                    <td style="text-align: right; border-bottom: 1px solid #000; color: #119911; font-weight: bold;">

                        500                     </td>

                </tr>

                <tr>

                    <td><a href="#" id="west3" title="Total Monthly earnings">Monthly Earnings</a></td>

                    <td style="text-align: right; color: #119911; font-weight: bold;">

                        1500                        </td>

                </tr>

                <tr>

                    <td><a href="#" id="west4" title="Total expenses">Total expended</a></td>

                    <td style="text-align: right; border-bottom: 1px solid #000; color: #880000; font-weight: bold;">

                        430                     </td>

                </tr>

                <tr>

                    <td><a href="#" id="west5" title="Total available">Account Balance</a></td>

                    <td style="text-align: right; border-bottom: 3px double #000; color: #119911; font-weight: bold;">

                        840                     </td>

                </tr>

                <tr>

                    <td></td>

                    <td style="padding: 5px;">

                        <center>

                            <form id="request_bill" method="POST" action="index.php?page=dashboard">

                                <input type="hidden" name="secret_token" value="" />

                                <input type="hidden" name="request_payout" value="1" />

                                <input type="submit" class="btn blue large" value="Request Payout" />

                            </form>

                        </center>

                    </td>

                </tr>

            </table>

        </div>

    </div>

</div>

如你所见,这个HTML格式不是很好,但我需要提取一些元素及其值,比如:“每日收入”和“150” | “每周收入”和“500”……

我觉得“id”属性可能会有帮助,但当我尝试解析时,程序就崩溃了。

我正在使用的Python代码是:

def parseo(archivohtml):
    html = archivohtml
    parsed_html = BeautifulSoup(html)
    par = parsed_html.find('td', attrs={'id':'west1'}).string
    print par

这里的archivohtml是登录后保存的HTML文件。

当我运行这个脚本时,只会出现错误。

我也尝试过这样做:

def parseo(archivohtml):
    soup = BeautifulSoup()
    html = archivohtml
    parsed_html = soup(html)
    par = soup.parsed_html.find('td', attrs={'id':'west1'}).string
    print par

但结果还是一样。

2 个回答

0

我从你的问题中看不出这个方法是否适合你,但这里有另一种方法:

def parseo(archivohtml):
    html = archivohtml
    parsed_html = BeautifulSoup(html)
    for line in parsed_html.stripped_strings:        
        print line.strip()

这个方法的结果是:

Account Balance
Daily Earnings
150
Weekly Earnings
500
Monthly Earnings
1500
Total expended
430
Account Balance
840

如果你想把数据放在一个列表里,可以这样做:

data = [line.strip() for line in parsed_html.stripped_strings]

[u'Account Balance', u'Daily Earnings', u'150', u'Weekly Earnings', u'500', u'Monthly Earnings', u'1500', u'Total expended', u'430', u'Account Balance', u'840']
1

带有 id="west1" 的标签是一个 <a> 标签。你需要找的是在这个 <a> 标签后面的 <td> 标签:

import BeautifulSoup as bs

content = '''<div class="widget_title clearfix">
        <h2>Account Balance</h2>
    </div>
    <div class="widget_body">
        <div class="widget_content">
            <table class="simple">
                <tr>
                    <td><a href="#" id="west1" title="Total earned daily">Daily Earnings</a></td>
                    <td style="text-align: right; width: 125px; color: #119911; font-weight: bold;">
                        150                         
                    </td>
                </tr>
                <tr>
                    <td><a href="#" id="west2" title="Total weekly earnings">Weekly Earnings</a></td>
                    <td style="text-align: right; border-bottom: 1px solid #000; color: #119911; font-weight: bold;">
                        500                     </td>
                </tr>
                <tr>
                    <td><a href="#" id="west3" title="Total Monthly earnings">Monthly Earnings</a></td>
                    <td style="text-align: right; color: #119911; font-weight: bold;">
                        1500                        </td>
                </tr>
                <tr>
                    <td><a href="#" id="west4" title="Total expenses">Total expended</a></td>
                    <td style="text-align: right; border-bottom: 1px solid #000; color: #880000; font-weight: bold;">
                        430                     </td>
                </tr>
                <tr>
                    <td><a href="#" id="west5" title="Total available">Account Balance</a></td>
                    <td style="text-align: right; border-bottom: 3px double #000; color: #119911; font-weight: bold;">
                        840                     </td>
                </tr>
                <tr>
                    <td></td>
                    <td style="padding: 5px;">
                        <center>
                            <form id="request_bill" method="POST" action="index.php?page=dashboard">
                                <input type="hidden" name="secret_token" value="" />
                                <input type="hidden" name="request_payout" value="1" />
                                <input type="submit" class="btn blue large" value="Request Payout" />
                            </form>
                        </center>
                    </td>
                </tr>
            </table>
        </div>
    </div>
</div>'''

def parseo(archivohtml):
    html = archivohtml
    parsed_html = bs.BeautifulSoup(html)
    par = parsed_html.find('a', attrs={'id':'west1'}).findNext('td')        
    print par.string.strip()

parseo(content)

结果是

150

撰写回答