用汤选择美丽汤中的第二个孩子?选择?

问题描述 投票:12回答:3

我有:

<h2 id='names'>Names</h2>
<p>John</p>
<p>Peter</p>

如果我已经拥有h2标签,那么现在最简单的方法就是将Peter带到这里?现在我试过了:

soup.select("#names > p:nth-child(1)")

但在这里我得到了nth-child NotImplementedError:

NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type.

所以我不确定这里发生了什么。第二种选择是让所有'p'标记子项并且硬选择[1]但是然后存在索引超出范围的危险,这将需要包围每次尝试以获得彼得的尝试/除了有点愚蠢。

有没有办法用soup.select()函数选择nth-child?

编辑:用nth-type替换nth-child似乎可以解决问题,所以正确的行是:

soup.select("#names > p:nth-of-type(1)")

不确定为什么它不接受nth-child但似乎nth-child和nth-of-type返回相同的结果。

python web-scraping beautifulsoup
3个回答
11
投票

将您的编辑添加为答案,以便其他人更容易找到它:

使用nth-of-type而不是nth-child

soup.select("#names > p:nth-of-type(1)")

8
投票

'nth-of-child'根本没有在beautifulsoup4中实现(在撰写本文时),beautifulsoup代码库中根本没有代码可以执行它。作者明确地添加了'NotImplementedError'来解释这个问题,here is the code

鉴于你在问题中引用的html,你不是在寻找一个h2#名字的孩子。

你真正想要的是第二个相邻的兄弟,我不是一个css选择大师,但我发现这很有效。

soup.select("#names + p + p")

2
投票

美丽的汤4.7.0(2019年初发布)now supports大多数选择器,包括:nth-child

从版本4.7.0开始,Beautiful Soup通过SoupSieve项目支持大多数CSS4选择器。如果您通过pip安装了Beautiful Soup,则SoupSieve同时安装,因此您无需执行任何额外操作。

所以,如果你升级你的版本:

pip install bs4 -U

您将能够使用几乎所有您需要的选择器,包括nth-child

也就是说,请注意,在您的输入HTML中,#names h2标记实际上没有任何子代:

<h2 id='names'>Names</h2>
<p>John</p>
<p>Peter</p>

这里只有3个元素,都是兄弟姐妹,所以

#names > p:nth-child(1)

即使在CSS或Javascript中也行不通。

如果#names元素将<p>s作为子元素,那么您的选择器将在某种程度上起作用:

html = '''
<div id='names'>
    <p>John</p>
    <p>Peter</p>
</div>
'''
soup = BeautifulSoup(html, 'html.parser')
soup.select("#names > p:nth-child(1)")

输出:

[<p>John</p>]

当然,John <p>#names父母的第一个孩子。如果你想要Peter,请使用:nth-child(2)

如果元素都是相邻的兄弟元素,则可以使用+选择下一个兄弟:

html = '''
<h2 id='names'>Names</h2>
<p>John</p>
<p>Peter</p>
'''
soup = BeautifulSoup(html, 'html.parser')
soup.select("#names + p + p")

输出:

[<p>Peter</p>]
© www.soinside.com 2019 - 2024. All rights reserved.