beautifulsoup:find_all bs4.element.ResultSet 对象或列表?

beautifulsoup: find_all on bs4.element.ResultSet object or list?

提问人:YJZ 提问时间:3/18/2016 最后编辑:cottontailYJZ 更新时间:11/2/2023 访问量:79382

问:

我应用一个对象,并找到一些东西,这是一个对象或一个.find_allbeautifulsoupbs4.element.ResultSetlist

我想在那里进一步做,但它不允许在对象上。我可以遍历对象的每个元素来做。但是我可以避免循环并将其转换回对象吗?find_allbs4.element.ResultSetbs4.element.ResultSetfind_allbeautifulsoup

这是我的代码:

html_1 = """
<table>
    <thead>
        <tr class="myClass">
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
    </thead>
</table>
"""
soup = BeautifulSoup(html_1, 'html.parser')

type(soup) #bs4.BeautifulSoup

# do find_all on beautifulsoup object
th_all = soup.find_all('th')

# the result is of type bs4.element.ResultSet or similarly list
type(th_all) #bs4.element.ResultSet
type(th_all[0:1]) #list

# now I want to further do find_all
th_all.find_all(text='A') #not work

# can I avoid this need of loop?
for th in th_all:
    th.find_all(text='A') #works
python html beautifulsoup html 解析

评论


答:

28赞 alecxe 3/19/2016 #1

ResultSetclass 是列表的子类,而不是定义了方法的 Tag。循环遍历结果是最常见的方法:find*find_all()

th_all = soup.find_all('th')
result = []
for th in th_all:
    result.extend(th.find_all(text='A'))

通常,CSS 选择器可以帮助您一次性解决它,但并非所有您可以使用该方法完成所有操作。例如,CSS选择器中没有可用的“文本”搜索。但是,例如,如果你必须找到所有元素,比如元素内部的元素,你可以这样做:find_all()select()bs4bth

soup.select("th td")

评论

1赞 Ayushi Dalmia 6/10/2016
将soup.find_all的结果复制到th_all后,对th_all进行更改会反映在汤中吗?
0赞 Bishwas Mishra 5/23/2017
是的,它会的。取决于您使用的功能。参考:beautiful-soup-4.readthedocs.io/en/latest/#modifying-the-tree
0赞 cottontail 11/2/2023 #2

我知道这已经晚了很多年了,但前几天我去了兔子洞,发现它是从 Python 列表(源代码)中子类化的;它实际上只是一个附加属性的列表,该属性通常是一个 null 对象。ResultSet.source

现在,回到 OP 的主要问题,在调用期间可以通过传递标签类型和它应该匹配的字符串来完成过滤。这将返回标记的 ResultSet(如下所示)。要提取这些标签中的实际文本,我们必须再次循环以遍历它。find_all()th_all

html_1 = """
<table>
    <thead>
        <tr class="myClass">
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
    </thead>
</table>
"""
soup = BeautifulSoup(html_1, 'html.parser')

th_all = soup.find_all('th', string='A')  # [<th>A</th>]

texts = [th.string for th in th_all]      # ['A']

回答问题的第二部分:

我们如何将 ResultSet 转换为 BeautifulSoup 对象?

我们可以明确地将其转换为一个。然后我们可以调用它。find_all()

th_all = soup.find_all('th')
soup2 = BeautifulSoup('\n'.join(map(str, th_all)))
soup2.find_all(string='A')   # ['A']

但是,由于我们已经可以对 ResultSet 进行搜索,因此在这种情况下可能并不可取。