Библиотека Beautiful Soup также предоставляет метод soup.find_all(), который позволяет найти все элементы, которые соответствуют указанным критериям. Всегда возвращает список элементов.
Общий синтаксис:
soup.find_all(name=None, attrs={}, recursive=True, string=None, limit=None, **kwargs)
Доступные параметры:
name – название тега HTML, который необходимо найти. Можно использовать строку с именем тега, регулярное выражение, список имен тегов и другие типы фильтров. Опциональный параметр.
attrs={} – словарь атрибутов со значениями. Опциональный параметр.
string=None – данный параметр позволяет искать элементы с определенным текстом. Может быть регулярным выражением, строкой или другим типом фильтра. Если параметр не установлен или значение – None, текстовое содержимое учитываться не будет. Опциональный параметр.
recursive=True. Определяет, будет ли поиск вестись только среди прямых потомков (False) или по всем дочерним элементам (True, значение по умолчанию). Опциональный параметр.
limit=None – максимальное количество элементов в результате поиска. Опциональный параметр.
Пример 1
Код осуществляет поиск тегов <p> при помощи метода find_all().
result = soup.find_all('p')
Поиск тегов <p>, которые имеют атрибуты class=’text-class’
result = soup.find_all('p', attrs={'class': 'text-class'})
Вывод текста из каждого найденного тега:
for tag in result: print(tag.text)
from bs4 import BeautifulSoup
html = """
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Пример использования BeautifulSoup</title>
</head>
<body>
<p>Первый абзац без атрибутов.</p>
<p class="text-class">Второй абзац с атрибутом class.</p>
<p id="text-id">Третий абзац с атрибутом id.</p>
<p class="text-class" id="text-id">Четвёртый абзац с атрибутами class и id.</p>
</body>
</html>
"""
soup = BeautifulSoup(html, 'html.parser')
# Найти все теги `p`
result = soup.find_all('p')
for tag in result:
print(tag.text)
print('----разделитель----')
# Найти все теги `p` с атрибутом class='text-class'
result = soup.find_all('p', attrs={'class': 'text-class'})
for tag in result:
print(tag.text)
print('----разделитель----')
# Найти все теги `p` с атрибутом id='text-id'
result = soup.find_all('p', attrs={'id': 'text-id'})
for tag in result:
print(tag.text)
Первый абзац без атрибутов. Второй абзац с атрибутом class. Третий абзац с атрибутом id. Четвёртый абзац с атрибутами class и id. ----разделитель---- Второй абзац с атрибутом class. Четвёртый абзац с атрибутами class и id. ----разделитель---- Третий абзац с атрибутом id. Четвёртый абзац с атрибутами class и id.
Пример 2
Использование метода для поиска всех тегов <a>, которые содержат атрибут href.
result = soup.find_all('a', href=True)
Результат заносится в переменную, далее при помощи цикла выводится текст внутри каждого тега.
soup = BeautifulSoup(html, 'html.parser')
# Найти все теги <a> с атрибутом href
result = soup.find_all('a', href=True)
for tag in result:
print(tag['href'], tag.text)
Пример 3. Использование recursive=True
Запускается поиск всех тегов <p>, включая все вложенные элементы.
from bs4 import BeautifulSoup
html_doc = """
<html>
<head>
<title>Example Page</title>
</head>
<body>
<div id="main">
<h1>Hello World</h1>
<p class="info">This is a paragraph.</p>
<p class="info">This is another paragraph.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div id="secondary">
<p>Some additional information.</p>
</div>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# Найти все теги p в HTML-документе, включая те, что находятся внутри вложенных тегов.
all_p_tags = soup.find_all('p', recursive=True)
print(all_p_tags)
Пример 4. Использование text
Производится поиск всех тегов <p>, текстовое содержимое должно строго совпадать со строкой «Текст 1». Далее в цикле производится итерация по списку с найденными тегами для вывода текста.
soup = BeautifulSoup(html, 'html.parser')
#1) Найти все теги `p` с текстом 'Текст 1'
result = soup.find_all('p', text='Текст 1')
for tag in result:
print(tag.text)
print('----разделитель----')
#2) Найти все теги `p` с текстом, содержащим 'Текст'
result = soup.find_all('p', text=lambda x: 'Текст' in x)
for tag in result:
print(tag.text)
В первой реализации в метод find_all() передается аргумент для фильтрации. Во втором случае используется проверка вхождения при помощи оператора in. Запускается проверка, встречается ли подстрока «Текст» в исходном тексте. Поскольку точное совпадение не требуется для срабатывания условия, появляется возможность более гибко настроить фильтрацию.
Пример 5
При помощи find_all() запускается поиск всех тегов <p> с определенными атрибутами id или class. Полученный список итерируется для вывода текста в консоль.
# Найти все теги <p> с классом `text-class`
result = soup.find_all('p', {'class': 'text-class'})
for tag in result:
print(tag.text)
print('----разделитель----')
# Найти все теги <p> с атрибутом `class`
result = soup.find_all('p', class_=True)
for tag in result:
print(tag.text)
print('----разделитель----')
# Найти все теги <p> с атрибутом `id`
result = soup.find_all('p', id=True)
for tag in result:
print(tag.text)