我有:
<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.
所以我不确定这里发生了什么。第二种选择是让所有人都能得到所有的&#39;标记儿童和硬选择[1]然后那里有索引超出范围的危险,这需要围绕每次尝试使用try / except Peter ,这有点愚蠢。
用soup.select()函数选择nth-child的任何方法?
修改 用nth-of-type替换nth-child似乎可以解决问题,所以正确的行是:
soup.select("#names > p:nth-of-type(1)")
不确定为什么它不接受n-child但似乎nth-child和nth-of-type都会返回相同的结果。
答案 0 :(得分:10)
将您的编辑添加为答案,以便其他人更容易找到:
使用All
代替nth-of-type
:
nth-child
答案 1 :(得分:8)
'nth-of-child'根本没有在beautifulsoup4中实现(在撰写本文时),beautifulsoup代码库中根本没有代码可以执行它。作者明确地添加了'NotImplementedError'来解释这个,here is the code
考虑到你在问题中引用的html,你不是在寻找一个h2#名字的孩子。
你真正想要的是第二个相邻的兄弟姐妹,我不是css选择大师,但我发现这很有效。
soup.select("#names + p + p")
答案 2 :(得分:1)
Beautiful Soup 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>
作为孩子,则您的选择器将在一定程度上起作用:
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>]