2

我正在使用 beautifulsoup 执行以下操作:
section = soup.findAll('tbody')[0]

如何使用第一个列表项设置这样的变量...而不抛出异常:IndexError: list index out of range如果 BS4 找不到 tbody?

有任何想法吗?

4

3 回答 3

5

每个解析 HTML 的人都会遇到这种类型的问题。您要查找的元素位于嵌套结构中... table -> tbody -> tr -> td ... etc...

但是,您需要记住以下几点:

(1) 您指定的路径越详细,以查找您的元素。如果您没有正确处理异常并且实际上,您的代码将更容易中断,您找到路径的逻辑可能根本不通用..

(2)尽量通过唯一的id或者classes来定位元素,而不是依赖一些通用标签的顺序。

(3) 如果您尝试收集的文本遵循某种模式。您可以使用文本本身轻松找到它,这对程序员来说更直接......文本是人们实际看到的。

import re
...
print soup.find_all(text=re.compile("pattern"))
# then you can find the element by calling parent of the found texts.

简而言之,在我看来,永远不要搜索“tbody”标签......因为代码总是这样:

<table..>
    <tbody>
        <tr>
        ...
    </tbody>
<table>

如果你已经找到了桌子,你可以这样做

table = soup.find('table'...)
# unless you are trying to not recursively find tr, then you have to find tobody first and find_all(recursive=FALSE)
table.find_all('tr')
于 2013-10-27T17:15:15.070 回答
4

您可以先返回答案findAll并检查它的长度:

x = soup.findAll("tbody")

if x is not None and len(x) > 0:
    section = x[0]
于 2013-10-27T12:44:10.077 回答
3

医生说_

因为 find_all() 是 Beautiful Soup 搜索 API 中最流行的方法,所以您可以使用它的快捷方式。如果您将 BeautifulSoup 对象或 Tag 对象视为一个函数,那么它与在该对象上调用 find_all() 相同。

所以在你的情况下,我认为你可以这样做:

if soup("tbody"):
    section = soup("tbody")[0]

请注意,在您的代码中,发生错误时section是一个空列表,但您正在尝试获取尚不存在的元素 [0]。在上面的代码中,您首先检查列表是否存在且不为空。如果检查通过,则您可以访问列表的第一个元素。

于 2013-10-27T16:55:48.463 回答