Поиск элементов по нескольким классам в BeautifulSoup4

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Методы BeautifulSoup findAll() и select() позволяют осуществлять поиск элементов по заданным классам:

Python
Скопировать код
soup.findAll("tag", class_=["class1", "class2"])  # Поиск элемента “tag” классом "class1" или "class2"
soup.select(".class1.class2")                     # Поиск элементов, одновременно классов "class1" и "class2"

Примечание: В findAll() подстановочный термин "tag" замените на интересующий тег, а "class1", "class2" – на требуемые классы. Метод select() вернёт элементы, содержащие оба класса.

Python
Скопировать код
import re
soup.findAll("tag", {"class": re.compile("class1|class2")})  # Поиск элемента “tag” классом "class1" или "class2" с помощью регулярных выражений

Регулярное выражение re.compile("class1|class2") поможет найти элементы, которые содержат class1 или class2.

Кинга Идем в IT: пошаговый план для смены профессии

Понимание принципов работы findAll()

В процессе веб-скрапинга часто требуется фильтр элементов по нескольким классам. BeautifulSoup предлагает разные подходы к решению данной задачи, соответствующие логикам ИЛИ (OR) и И (AND).

Поиск элементов по одному из классов (логика ИЛИ)

Для поиска элементов, совпадающих с любым из указанных классов, применяется findAll():

Python
Скопировать код
elements = soup.findAll("tag", class_=["class1", "class2"])  # Поиск элемента “tag” классом "class1" или "class2"

Поиск элементов по всем классам (логика И)

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

Python
Скопировать код
elements = soup.select(".class1.class2")  # Поиск элемента “tag” классами "class1" и "class2"

Применение регулярных выражений для сложных запросов

Регулярные выражения пригодятся для формирования более сложных условий поиска:

Python
Скопировать код
elements = soup.findAll("tag", {"class": re.compile("^class1.*class2$")})  # Более сложный запрос с помощью регулярных выражений

Паттерн ^class1.*class2$ поможет найти классы, которые начинаются с class1 и заканчиваются class2.

Сохранение порядка элементов во время парсинга

BeautifulSoup умеет сохранять последовательность элементов в том порядке, в котором они представлены в исходном HTML, что критично важно для корректного понимания и сохранения данных.

Обработка реальных случаев

Учёт порядка при использовании findAll()

Используйте findAll() с указанием списка классов, чтобы сохранить порядок элементов. Это особенно актуально при работе с таблицами, где важно не нарушить исходную структуру.

Применение сессий для сохранения состояния при процедуре скрапинга

На сайтах с сессиями создавайте сессионные запросы с помощью библиотеки requests, что гарантирует устойчивое сопряжение между запросами:

Python
Скопировать код
import requests
from bs4 import BeautifulSoup

session = requests.Session()
response = session.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')

# Теперь с помощью soup.findAll можно изучить страницы, сохраняя контекст

Работа со сложноструктурированными и динамическими классами

Для решения задач, связанных с динамическими классами, применяйте модуль re Python:

Python
Скопировать код
import re
dynamic_elements = soup.findAll("tag", {"class": re.compile("^class1.*class2$")})  # Использование регулярных выражений

Визуализация

Давайте рассмотрим аналогию: представьте себя флористом, выбирающим разные сорта цветов (🌸, 🌺, 🌼) в зависимости от их категорий (findAll()):

Markdown
Скопировать код
Изысканные перчатки (findAll()): [🌸, 🌺, 🌼]
Категории цветов (Классы): 🌸(Роза), 🌺(Тюльпан), 🌼(Ромашка)

Флорист может выбирать разные категории одновременно:

Python
Скопировать код
florist_gloves.findAll(class_=["Rose", "Tulip"])

В руках флориста оказываются:

Markdown
Скопировать код
👐🌸🌺: [🌸(Розы), 🌺(Тюльпаны)]

Действуя по аналогии с флористом, мы выбираем элементы нашего HTML-сада, применяя findAll().

Тщательный анализ данных

Для более точного вычленения информации из определённого вложенного класса пройдите по элементам в цикле, уточняя запрос:

Python
Скопировать код
for parent in soup.find_all("div", class_="parent-class"):
    children = parent.find_all("span", class_="child-class")
    # Таким образом, будут найдены все теги span с классом "child-class", которые расположены в дивах с классом "parent-class".

Селекторы CSS

Если требуется максимальная точность и контроль над поиском, select() в BeautifulSoup предоставляет возможность работы с селекторами CSS:

Python
Скопировать код
articles = soup.select("div.content > p.story.story-highlight")
# Здесь осуществляется поиск каждого элемента <p> с классами "story" и "story-highlight", являющегося прямым потомком <div> с классом "content".

Полезные материалы