</>
Topic 3 of 5

Course materials are currently available in Russian only.

CSS-селекторы

Искать теги через find с параметрами удобно, пока условие простое. Для сложных условий — «ссылки внутри второго блока с классом item, кроме рекламных» — есть язык CSS-селекторов. Им же пользуются веб-разработчики, чтобы описывать стили, поэтому селекторы для любой страницы легко подсмотреть в инструментах разработчика браузера.

select и select_one

soup.select("li")          # список всех подходящих тегов (может быть пустым)
soup.select_one("li")      # первый подходящий или None
card.select("span")        # поиск внутри найденного тега

Основы селекторов

Селектор Что выбирает
p все теги <p>
.price теги, у которых среди классов есть price
p.note теги <p> с классом note
.card.sale теги, у которых есть оба класса
#main тег с id="main"
h2, h3 все <h2> и все <h3> (в порядке документа)

Вложенность

  • div a (через пробел) — <a>, которые находятся где-то внутри <div>, на любой глубине;
  • div > a — только прямые потомки: <a> непосредственно внутри <div>;
  • селекторы можно сцеплять: #news .item > a.
html = "<ul><li>1<ul><li>1.1</li></ul></li></ul>"
soup = BeautifulSoup(html, "html.parser")
print(len(soup.select("ul li")))     # 2 — оба li
print(len(soup.select("ul > li")))   # 2 — каждый li — прямой потомок своего ul
print(len(soup.select("body > ul"))) # 0 — тега body в этом документе нет

Атрибуты

Селектор Что выбирает
a[href] ссылки, у которых есть атрибут href
a[target="_blank"] атрибут равен значению
a[href^="https"] значение начинается с https
img[src$=".png"] значение заканчивается на .png
div[class="product"] атрибут class в точности равен строке product

Последний пример — ловушка: <div class="product sale"> под него не подходит, а под div.product — подходит.

Атрибуты вида data-что-то — место, где разработчики хранят служебные данные: цены, идентификаторы. Читаются они как обычные: li["data-price"].

Исключения: :not

li:not(.done) — все <li>, у которых нет класса done. Внутри :not можно писать любой простой селектор: a:not([href^="http"]) — ссылки, адрес которых не начинается с http.

Итог

  • select(селектор) — список, select_one(селектор) — первый или None;
  • .класс, #id, тег.класс, A B (внутри), A > B (прямо внутри), A, B (или);
  • [атрибут], [атрибут="значение"], ^= начинается, $= заканчивается;
  • :not(...) — исключение.