带有 :not 的 CSS 选择器未按预期运行
Posted
技术标签:
【中文标题】带有 :not 的 CSS 选择器未按预期运行【英文标题】:CSS selector with :not does not behave as expected 【发布时间】:2019-11-16 11:56:43 【问题描述】:<p class="p_cat_heading">SOUND WORD</p>
<p class="p_normal__and__avoid_page_break_after"><span class="c_tone_char">Vene</span><span class="c_tone_char__and__underline">zue</span><span class="c_tone_char">la</span> /<span class="calibre22">venedswela</span>/</p>
<p class="p_normal__and__avoid_page_break_after">South American country over the equator, known in part for its sunny beaches. Pronounce it in Italian for a better sound match.</p>
<p class="p_normal__and__avoid_page_break_after"><img src="../images/00461.jpeg" class="calibre18"/></p>
<p class="p_cat_heading__and__centre_alignment">COMPONENTS</p>
我正在使用以下 CSS 选择器:
content = str(soup.select_one('.p_cat_heading:contains("SOUND WORD") + :not(.p_cat_heading)')) # type: str
这应该选择所有直到具有类 p_cat_heading 的元素。但是它只选择:
<p class="p_normal__and__avoid_page_break_after"><span class="c_tone_char">Vene</span><span class="c_tone_char__and__underline">zue</span><span class="c_tone_char">la</span> /<span class="calibre22">venedswela</span>/</p>
我一定误解了 CSS 选择器的工作原理。我认为:
像 Python 切片一样工作,但似乎并非如此。也就是说,我不确定我错过了什么。
【问题讨论】:
用select
替换select_one
这不是 CSS 中 +
运算符的工作方式。 selector1 + selector2
匹配匹配 selector2
的元素,该元素紧跟在匹配 selector1
的元素之后。它与中间的所有元素都不匹配。
@abdusco - 试一试,但它不起作用
@Barmar 啊,这就解释了!那么有没有一种语法可以让你在两者之间获得一切?
我不这么认为。
【参考方案1】:
感谢@Barmar 在这方面的帮助。重申他的评论,您不能使用 CSS 选择器来执行此操作。相反,我所做的是遍历元素直到到达分隔符:
for temp_heading in heading.find_next_siblings():
if temp_heading.attrs["class"][0] == "p_cat_heading":
break
else:
print(str(temp_heading))
organized_entry["soundword"] = content
其中 temp_heading 是 bs.element.Tag 的一个实例,它从指向开始:
<p class="p_cat_heading">SOUND WORD</p>
【讨论】:
【参考方案2】:如果如您所见,您可以使用过滤并从第一个搜索字符串的同级 p 标签中过滤掉作为第二个搜索字符串或以下同级的 p 标签。这是非常具体的,以匹配您所展示的内容。
from bs4 import BeautifulSoup as bs
html = '''
<html>
<head></head>
<body>
<p class="p_cat_heading">SOUND WORD</p>
<p class="p_normal__and__avoid_page_break_after"><span class="c_tone_char">Vene</span><span class="c_tone_char__and__underline">zue</span><span class="c_tone_char">la</span> /<span class="calibre22">venedswela</span>/</p>
<p class="p_normal__and__avoid_page_break_after">South American country over the equator, known in part for its sunny beaches. Pronounce it in Italian for a better sound match.</p>
<p class="p_normal__and__avoid_page_break_after"><img src="../images/00461.jpeg" class="calibre18"></p>
<p class="p_cat_heading__and__centre_alignment">COMPONENTS</p>
</body>
</html>
'''
soup = bs(html, 'lxml')
result = [item.text.strip() for item in soup.select('p:contains("SOUND WORD") ~ p:not(p:contains("COMPONENTS") ~ p, p:contains("COMPONENTS"))')]
【讨论】:
以上是关于带有 :not 的 CSS 选择器未按预期运行的主要内容,如果未能解决你的问题,请参考以下文章