【问题标题】:BeautifulSoup in Python - getting the n-th tag of a typePython中的BeautifulSoup - 获取类型的第n个标签
【发布时间】:2012-12-15 06:05:14
【问题描述】:

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

我正在尝试获取第二个表中的信息。有没有办法在不使用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

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

【问题讨论】:

  • 只是soup.findAll('table')不会导致ValueError。请发布您的完整代码。 too many values to unpack 表示左侧表达式中有多个变量。
  • soup.find(title="things") ??
  • 在帖子的顶部,我说我在代码中使用了它,其中包含许多 <table>s。我在这个页面上使用它:view-source:dhmc.us/players/view/nasonfish 并且正在使用这个代码:table1, table2 = soup.find_all('table')
  • soup.find_all('table') 返回一个列表。 tables = soup.find_all('table') 应该可以工作
  • @nasonfish:错误显示您有超过 2 个表,因此解包失败。在这种情况下不要使用元组解包。

标签: python beautifulsoup


【解决方案1】:

这是我的版本

# 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'

【讨论】:

    【解决方案2】:

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

    当您尝试find_all 并获取第 n 个元素时,您可能会搞砸,您最好找到您想要的第一个元素并确保第 n 个元素实际上是该元素的兄弟孩子的。

    1. 您可以使用find_next_sibling() 来保护您的代码
    2. 您可以先找到父节点,然后使用 find_all(recursive=False) 来保证您的搜索范围。

    以备不时之需。我将在下面列出我的代码(使用 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
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 这非常有效。谢谢!不知道为什么我以前没有想到这一点。
      • findAll('table')[1] 的真正含义是什么?是先找到第二个表还是先找到所有表再获取第二个表?
      • @CokileChui 它先找到所有表,然后获取第二个表。 FindAll 是一个函数,它的返回值给出一个列表,然后我们得到它的第二个元素
      猜你喜欢
      • 2016-12-24
      • 2016-03-26
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2020-12-06
      • 2021-12-06
      • 1970-01-01
      • 2012-02-02
      相关资源
      最近更新 更多