[英]CSS selector with :not does not behave as expected
我想使用CSS选择器在Python中使用CSS选择器选择具有SOUND WORD值的元素之后,但具有值称为COMPONENTS的元素之前的所有内容。
<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 width="30%" alt="" 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切片一样工作,但事实并非如此。 也就是说,我不确定我缺少什么。
感谢@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>
如果您显示的是,则可以使用过滤并过滤掉第二个搜索字符串中的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 width="30%" alt="" 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"))')]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.