Python中的BeautifulSoup - 获取类型的第n个标记

时间:2012-12-30 22:50:23

标签: python beautifulsoup

我有一些html代码,其中包含许多<table>

我正在尝试在第二个表格中获取信息。有没有办法在不使用soup.findAll('table')的情况下执行此操作?

当我使用soup.findAll('table')时,出现错误:

ValueError: too many values to unpack

有没有办法在某些代码中获取第n个标记或者不需要遍历所有表的其他方式?或者我应该看看我是否可以在表格中添加标题? (如<table title="things">

每个表格上方还有标题(<h4>title</h4>),如果有帮助的话。

感谢。

修改

这就是我在问这个问题时的想法:

我将对象解包为两个值,当还有更多时。我认为这只会给我列表中的前两个东西,但当然,它一直给我上面提到的错误。我不知道返回值是一个列表,并认为它是一个特殊的对象或东西,我把我的代码基于我的朋友。

我认为这个错误意味着页面上有太多的表,并且它无法处理所有这些表,所以我想要一种方法来实现它而不使用我正在使用的方法。我可能应该停止假设。

现在我知道它会返回一个列表,我可以在for循环中使用它,或者使用soup.findAll('table')[someNumber]从中获取一个值。我了解了拆包的内容以及如何使用它。谢谢所有帮助过的人。

希望能够解决问题,既然我知道自己在做什么,那么问题就会比我提出的问题更有意义,所以我想我只是在这里记下我的想法。

编辑2:

这个问题现在很老了,但我仍然看到我从未真正清楚自己在做什么。

如果它对任何人都有帮助,我试图解压findAll(...)个结果,其中我不知道这些结果。

useless_table, table_i_want, another_useless_table = soup.findAll("table");

由于我在页面中没有总是猜到的表数量,并且元组中的所有值都需要解压缩,所以我收到了ValueError

ValueError: too many values to unpack

所以,我一直在寻找方法来获取返回的元组中的第二个(或哪个索引)表,而不会遇到有关使用了多少个表的错误。

3 个答案:

答案 0 :(得分:18)

要从调用soup.findAll('table')获取第二个表,请将其用作列表,只需将其编入索引:

secondtable = soup.findAll('table')[1]

答案 1 :(得分:2)

Martjin Pieter的回答将确实有效。我有一些嵌套table标签的经验,当我只是简单地获取列表中的第二个表而没有引起注意时,它破坏了我的代码。

当你尝试find_all并获得第n个元素时,你可能会陷入困境,你最好找到你想要的第一个元素,并确保第n个元素实际上是一个兄弟元素而不是孩子。

  1. 您可以使用find_next_sibling()来保护您的代码
  2. 您可以先找到父级,然后使用find_all(recursive = False)来保证您的搜索范围。
  3. 万一你需要它。我将在下面列出我的代码(使用recursive = FALSE)。

    import urllib2
    from bs4 import BeautifulSoup
    
    text = """
    <html>
        <head>
        </head>
        <body>
            <table>
                <p>Table1</p>
                <table>
                    <p>Extra Table</p>
                </table>
            </table>
            <table>
                <p>Table2</p>
            </table>
        </body>
    </html>
    """
    
    soup = BeautifulSoup(text)
    
    tables = soup.find('body').find_all('table')
    print len(tables)
    print tables[1].text.strip()
    #3
    #Extra Table # which is not the table you want without warning
    
    tables = soup.find('body').find_all('table', recursive=False)
    print len(tables)
    print tables[1].text.strip()
    #2
    #Table2 # your desired output
    

答案 2 :(得分:0)

这是我的版本

# Import bs4
from bs4 import BeautifulSoup

# Read your HTML
#html_doc = your html

# Get BS4 object
soup = BeautifulSoup(html_doc, "lxml")

# Find next Sibling Table to H3 Header with text "THE GOOD STUFF"    
the_good_table = soup.find(name='h3', text='THE GOOD STUFF').find_next_sibling(name='table')

# Find Second tr in your table
your_tr = the_good_table.findAll(name='tr')[1]

# Find Text Value of First td in your tr
your_string = your_tr.td.text

print(your_string)

输出:

'I WANT THIS STRING'