Псевдоклассы "has :()" и "not :()" ведут себя иначе при использовании в BeautifulSoup - PullRequest
2 голосов
/ 27 июня 2019

Я пытаюсь выяснить, как css pseudo-classes как 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 error.

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)

Где я иду не так и как я могу заставить их работать?

1 Ответ

3 голосов
/ 27 июня 2019

К сожалению, ваше понимание того, что делают :not() и :has(), скорее всего, неверно.

В первом примере вы используете:

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

То, как вы его используете, будет выбирать каждый tr. Это потому, что он говорит: «Я хочу тег tr, который не является тегом a. Теги tr никогда не являются тегами a, поэтому ваш код всегда захватывает текст любого тега tr, включая тот, который содержит 27A-TAX DISTRICT.

Если вы хотите, чтобы теги tr не имели тегов a, вы можете использовать:

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

Это говорит о том, что «я хочу тег tr, у которого нет тега a потомка».

Для получения дополнительной информации читайте:


Это приводит нас ко второму вопросу. :has() - реляционный селектор. Во втором примере вы использовали:

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

:has() смотрит вперед на потомков, потомков или братьев и сестер (в зависимости от используемого вами синтаксиса), чтобы определить, является ли тег тем, который вам нужен.

То, что вы сказали, было: «Я хочу тег p, который имеет тег-потомок с классом vital». Ни один из ваших тегов p даже не имеет потомков, поэтому нет никакого способа получить класс vital. То, что вы хотите, на самом деле проще:

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

Это говорит о том, что "я хочу тег p, который также имеет класс vital."

Для получения дополнительной информации читайте:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...