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(...)— исключение.