Библиотека 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)