Поиск элементов по нескольким классам в BeautifulSoup4
Быстрый ответ
Методы BeautifulSoup findAll()
и select()
позволяют осуществлять поиск элементов по заданным классам:
soup.findAll("tag", class_=["class1", "class2"]) # Поиск элемента “tag” классом "class1" или "class2"
soup.select(".class1.class2") # Поиск элементов, одновременно классов "class1" и "class2"
Примечание: В findAll()
подстановочный термин "tag"
замените на интересующий тег, а "class1"
, "class2"
– на требуемые классы. Метод select()
вернёт элементы, содержащие оба класса.
import re
soup.findAll("tag", {"class": re.compile("class1|class2")}) # Поиск элемента “tag” классом "class1" или "class2" с помощью регулярных выражений
Регулярное выражение re.compile("class1|class2")
поможет найти элементы, которые содержат class1
или class2
.
Понимание принципов работы findAll()
В процессе веб-скрапинга часто требуется фильтр элементов по нескольким классам. BeautifulSoup предлагает разные подходы к решению данной задачи, соответствующие логикам ИЛИ (OR) и И (AND).
Поиск элементов по одному из классов (логика ИЛИ)
Для поиска элементов, совпадающих с любым из указанных классов, применяется findAll()
:
elements = soup.findAll("tag", class_=["class1", "class2"]) # Поиск элемента “tag” классом "class1" или "class2"
Поиск элементов по всем классам (логика И)
Для поиска тегов, которые содержат все перечисленные классы, используется метод select()
:
elements = soup.select(".class1.class2") # Поиск элемента “tag” классами "class1" и "class2"
Применение регулярных выражений для сложных запросов
Регулярные выражения пригодятся для формирования более сложных условий поиска:
elements = soup.findAll("tag", {"class": re.compile("^class1.*class2$")}) # Более сложный запрос с помощью регулярных выражений
Паттерн ^class1.*class2$
поможет найти классы, которые начинаются с class1
и заканчиваются class2
.
Сохранение порядка элементов во время парсинга
BeautifulSoup умеет сохранять последовательность элементов в том порядке, в котором они представлены в исходном HTML, что критично важно для корректного понимания и сохранения данных.
Обработка реальных случаев
Учёт порядка при использовании findAll()
Используйте findAll()
с указанием списка классов, чтобы сохранить порядок элементов. Это особенно актуально при работе с таблицами, где важно не нарушить исходную структуру.
Применение сессий для сохранения состояния при процедуре скрапинга
На сайтах с сессиями создавайте сессионные запросы с помощью библиотеки requests, что гарантирует устойчивое сопряжение между запросами:
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:
import re
dynamic_elements = soup.findAll("tag", {"class": re.compile("^class1.*class2$")}) # Использование регулярных выражений
Визуализация
Давайте рассмотрим аналогию: представьте себя флористом, выбирающим разные сорта цветов (🌸
, 🌺
, 🌼
) в зависимости от их категорий (findAll()
):
Изысканные перчатки (findAll()): [🌸, 🌺, 🌼]
Категории цветов (Классы): 🌸(Роза), 🌺(Тюльпан), 🌼(Ромашка)
Флорист может выбирать разные категории одновременно:
florist_gloves.findAll(class_=["Rose", "Tulip"])
В руках флориста оказываются:
👐🌸🌺: [🌸(Розы), 🌺(Тюльпаны)]
Действуя по аналогии с флористом, мы выбираем элементы нашего HTML-сада, применяя findAll()
.
Тщательный анализ данных
Для более точного вычленения информации из определённого вложенного класса пройдите по элементам в цикле, уточняя запрос:
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:
articles = soup.select("div.content > p.story.story-highlight")
# Здесь осуществляется поиск каждого элемента <p> с классами "story" и "story-highlight", являющегося прямым потомком <div> с классом "content".