python - "has:()"和 "not:()"伪类在 BeautifulSoup 中使用时表现不同

标签 python python-3.x beautifulsoup css-selectors

我想弄清楚 css 伪类not:()has:() 是如何在下面工作的例。

下面的选择器不应该打印 27A-TAX DISTRICT 27A 但它打印了它:

from bs4 import BeautifulSoup

htmlelement = """
<tbody>
  <tr style="">
     <td><a>27A-TAX DISTRICT</a> 27A</td>
  </tr>

  <tr style="">
     <td><strong>Parcel Number</strong> 720</td>
  </tr>
</tbody>
"""
soup = BeautifulSoup(htmlelement,"lxml")
item = soup.select_one("tr:not(a)").text
print(item)

另一方面,下面的选择器应该打印 I should be printed 但它抛出 AttributeError 错误。

from bs4 import BeautifulSoup

htmlelement = """
<p class="vital">I should be printed</p>
<p>I should not be printed</p>
"""
soup = BeautifulSoup(htmlelement,"lxml")
item = soup.select_one("p:has(.vital)").text
print(item)

我哪里出错了,我怎样才能让它们起作用?

最佳答案

不幸的是,您对 :not():has() 的理解很可能是不正确的。

在您的第一个示例中,您使用:

soup.select_one("tr:not(a)").text

您使用它的方式将选择每个 tr。这是因为它说“我想要一个不是 a 标签的 tr 标签。tr 标签永远不是 a 标签,以便您的代码始终获取任何 tr 标签的文本,包括包含 27A-TAX DISTRICT 的标签。

如果你想要 tr 标签没有 a 标签,那么你可以使用:

soup.select_one("tr:not(:has(a))").text

这表示“我想要一个没有后代 a 标签的 tr 标签”。

更多信息请阅读:


这引出了您的第二个问题。 :has() 是一个关系选择器。在你的第二个例子中,你使用了:

soup.select_one("p:has(.vital)").text

:has() 向前看 child 、后代或 sibling (取决于您使用的语法)以确定标签是否是您想要的。

所以你说的是“我想要一个 p 标签,它有一个带有类 vital 的后代标签”。您的 p 标签甚至都没有后代,因此不可能有 vital 类。你想要的其实更简单:

soup.select_one("p.vital").text

这表示“我想要一个 p 标签,它也有一个 vital 类。”

更多信息请阅读:

关于python - "has:()"和 "not:()"伪类在 BeautifulSoup 中使用时表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56791505/

相关文章:

python - 在并发进程池期间从磁盘读取 pandas

python - django项目中搜索功能的实现

Python - BeautifulSoup,在标签中获取标签

python - xbmc/kodi python 使用 BeautifulSoup 抓取数据

python - 运行时错误: maximum recursion depth exceeded in cmp: K means clustering

python - Pandas - 获取字符串中的列表 df 列名称(例如)

python - 在pygame中旋转图像

python - 尝试读取大型网站文件数据时出现 MemoryError 异常

python - Pandas :与先前值(value)的差异

python - Google API 授权(服务帐户)错误 : HttpAccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request