繁体   English   中英

用soup.select在美丽的汤中选择第二个孩子?

[英]selecting second child in beautiful soup with soup.select?

我有:

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

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

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

但在这里我得到了第 n 个孩子 NotImplementedError:

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

所以我不确定这里发生了什么。 第二种选择是只获取所有 'p' 标签子项并硬选择 [1],但是存在索引超出范围的危险,这需要围绕每次尝试使用 try/except 获取Peter ,这有点愚蠢。

有什么办法可以用soup.select()函数选择第n个孩子?

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

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

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

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

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

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

'nth-of-child' 根本没有在 beautifulsoup4 中实现(在撰写本文时),beautifulsoup 代码库中根本没有代码可以做到这一点。 作者明确添加了“NotImplementedError”来解释这一点, 这是代码

鉴于您在问题中引用的 html,您不是在寻找 h2#names 的孩子。

您真正要寻找的是第二个相邻的兄弟姐妹,我不是 css 选择器大师,但我发现这行得通。

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

Beautiful Soup 4.7.0(2019 年初发布) 现在支持大多数选择器,包括: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>作为元素,则您的选择器在一定程度上可以工作:

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父级的第一个子#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>]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM