Важное предупреждение !!!
Данная статья носит исключительно информационный и образовательный характер. Она не является юридической консультацией и не может использоваться как руководство к действию в вопросах, связанных с парсингом, сбором данных и соблюдением законодательства.
Все примеры и рекомендации приведены для ознакомления с технической стороной процесса. Решение о законности парсинга в каждом конкретном случае зависит от множества факторов: юрисдикции, содержания сайта, способа сбора данных и целей использования информации. Для получения юридически обоснованного ответа обращайтесь к квалифицированным специалистам.
Перед началом прочтения статьи, ОБЯЗАТЕЛЬНО ознакомтесь со статьей «Что такое парсинг сайтов: законно ли это?«
Автор и администрация сайта не несут ответственности за использование материалов данной статьи в коммерческих или иных целях, а также за любые последствия, связанные с применением описанных методов.
Привет! В прошлой статье мы установили BeautifulSoup и написали первый парсер. Теперь пришло время научиться искать элементы на веб-странице. Это самое важное в парсинге — умение находить нужные теги.
В этой статье мы разберём:
find()— поиск первого элементаfind_all()— поиск всех элементов- Поиск по классам, id, атрибутам
- CSS-селекторы через
select()
- Что нужно знать перед началом
- Основная часть
- Метод find()
- Метод find_all()
- Поиск по классу
- Поиск по id
- Поиск по атрибутам
- Поиск по тексту
- Поиск с рекурсивным обходом
- CSS-селекторы через select()
- Пример из реальной жизни
- Задачи для закрепления
- Нюансы и подводные камни
- class_ с подчёркиванием
- find_all() возвращает список
- Поиск по нескольким классам
- Частые ошибки и как их избежать
- Ошибка 1: Забыл подчёркивание в class_
- Ошибка 2: Неправильное имя тега
- Ошибка 3: Ожидание списка от find()
- Шпаргалка
- 7. Заключение / Выводы
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный BeautifulSoup (статья 2 в этом подменю)
- Базовое понимание HTML-тегов
Совет: Умение искать элементы — это 80% всей работы парсера.
Основная часть
Метод find()
find() возвращает первый элемент, соответствующий критериям.
from bs4 import BeautifulSoup
html = """
<div class="content">
<h1>Заголовок</h1>
<p>Первый параграф</p>
<p>Второй параграф</p>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
first_p = soup.find("p")
print(first_p.text) # Первый параграфСинтаксис:
soup.find(name, attrs, recursive, string, **kwargs)Основные параметры:
| Параметр | Что делает |
|---|---|
name | Имя тега ("p", "div", "a") |
attrs | Атрибуты тега (class_, id) |
string | Поиск по тексту |
Метод find_all()
find_all() возвращает список всех элементов, соответствующих критериям.
soup = BeautifulSoup(html, "html.parser")
paragraphs = soup.find_all("p")
for p in paragraphs:
print(p.text)
# Выведет:
# Первый параграф
# Второй параграфВажно: Если элементов нет,
find_all()возвращает пустой список, а неNone.
items = soup.find_all("div")
print(items) # [] (пустой список)Поиск по классу
html = """
<div class="article">
<p class="title">Заголовок</p>
<p class="content">Текст статьи</p>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
title = soup.find("p", class_="title")
print(title.text) # Заголовок
content = soup.find("p", class_="content")
print(content.text) # Текст статьиСовет: Используй
class_с подчёркиванием, чтобы не конфликтовать с ключевым словомclassв Python.
Поиск по id
html = """
<div id="main">
<p>Главный текст</p>
</div>
<div id="footer">
<p>Подвал</p>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
main = soup.find(id="main")
print(main.p.text) # Главный текст
footer = soup.find(id="footer")
print(footer.p.text) # ПодвалПоиск по атрибутам
html = """
<a href="https://example.com">Ссылка</a>
<a href="https://google.com">Google</a>
"""
soup = BeautifulSoup(html, "html.parser")
# Поиск по атрибуту href
example_link = soup.find("a", href="https://example.com")
print(example_link.text) # Ссылка
# Поиск по атрибуту с помощью словаря
google_link = soup.find("a", attrs={"href": "https://google.com"})
print(google_link.text) # GoogleПоиск по тексту
html = """
<p>Привет, мир!</p>
<p>Hello, world!</p>
"""
soup = BeautifulSoup(html, "html.parser")
# Поиск по тексту
element = soup.find(string="Привет, мир!")
print(element) # Привет, мир!
# Поиск с частичным совпадением
import re
elements = soup.find_all(string=re.compile("мир"))
for el in elements:
print(el) # Привет, мир!Совет: Для частичного поиска используй модуль re (регулярные выражения).
Поиск с рекурсивным обходом
По умолчанию find() и find_all() ищут по всему дереву HTML. Можно ограничить поиск:
html = """
<div>
<p>Параграф в div</p>
<span>
<p>Вложенный параграф</p>
</span>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
# Поиск только внутри div
div = soup.find("div")
paragraphs = div.find_all("p", recursive=False)
print(len(paragraphs)) # 1 (только прямой потомок)CSS-селекторы через select()
BeautifulSoup поддерживает CSS-селекторы через метод select().
html = """
<div class="container">
<p id="first">Первый</p>
<p class="second">Второй</p>
<p>Третий</p>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
# Поиск по id
element = soup.select("#first")
print(element[0].text) # Первый
# Поиск по классу
elements = soup.select(".second")
print(elements[0].text) # Второй
# Поиск по тегу внутри класса
elements = soup.select(".container p")
for el in elements:
print(el.text)
# Первый
# Второй
# ТретийОсновные CSS-селекторы:
| Селектор | Что ищет |
|---|---|
#id | По id |
.class | По классу |
tag | По тегу |
tag.class | Тег с классом |
tag#id | Тег с id |
parent child | Вложенные элементы |
Пример из реальной жизни
Парсинг заголовков новостей с сайта:
import requests
from bs4 import BeautifulSoup
url = "https://news.ycombinator.com/"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
# Ищем все заголовки новостей (обычно внутри тега a с классом storylink)
titles = soup.find_all("a", class_="storylink")
for title in titles:
print(title.text)
print(title.get("href"))
print("-" * 40)Задачи для закрепления
Задача 1. Найди первый параграф на странице с помощью find().
Задача 2. Найди все ссылки на странице с помощью find_all().
Задача 3. Найди элемент с классом «highlight».
Задача 4. Найди элемент с id «main-content».
Задача 5. В чём разница между find() и find_all()?
Ответы:
Задача 1.
soup.find("p")Задача 2.
soup.find_all("a")Задача 3.
soup.find(class_="highlight")Задача 4.
soup.find(id="main-content")Задача 5.
# find() возвращает первый элемент или None
# find_all() возвращает список всех элементов или пустой списокНюансы и подводные камни
class_ с подчёркиванием
В Python class — зарезервированное слово, поэтому используется class_.
# Правильно
soup.find("p", class_="title")
# Неправильно
soup.find("p", class="title") # SyntaxErrorfind_all() возвращает список
items = soup.find_all("p")
if items:
print(len(items))
else:
print("Элементов нет")Поиск по нескольким классам
soup.find("div", class_="content main")Частые ошибки и как их избежать
Ошибка 1: Забыл подчёркивание в class_
Всегда используй class_, а не class.
Ошибка 2: Неправильное имя тега
Проверь регистр: "div" ≠ "DIV".
Ошибка 3: Ожидание списка от find()
find() возвращает один элемент или None, а не список.
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Найти первый элемент | soup.find("tag") |
| Найти все элементы | soup.find_all("tag") |
| Поиск по классу | soup.find("tag", class_="name") |
| Поиск по id | soup.find(id="name") |
| Поиск по атрибуту | soup.find("tag", attrs={"key": "value"}) |
| CSS-селектор | soup.select(".class") |
7. Заключение / Выводы
Сегодня мы:
- Научились искать элементы с помощью
find()иfind_all() - Искали по тегам, классам, id и атрибутам
- Познакомились с CSS-селекторами
- Разобрали частые ошибки








