BeautifulSoup используется для эффективного поиска элементов на html странице.
Установка:
pip install beautifulsoup4, lxml
Для запросов установите библиотеку requests, если она у вас не установлена:
pip install requests
Тренироваться будем на "тренажёре".
Получаем HTML-документ по HTTP и строим DOM-дерево с помощью BeautifulSoup
from bs4 import BeautifulSoup
import requests
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
soup = BeautifulSoup(response.text, 'lxml')
print(soup)
Первым параметром мы передаем html-код страницы, а вторым парсер. Помимо lxml (это лучший вариант) парсер может быть:
html.parser - не прощает ошибок в html, зато не требует установки
html5lib - более медленный, чем lxml, требует установки
xml - для распарса xml страниц
Пример того, как можно считать код из html файла на пк.
from bs4 import BeautifulSoup
import requests
with open('test.html', 'r', encoding='utf-8') as file:
soup = BeautifulSoup(file, 'lxml')
print(soup.prettify()) # prettify делает красивый вывод html
Также на всякий случай напомню вам, что страницы состоят из html тэгов. У тэгов могут быть атрибуты, а у атрибутов значения.
Кроме того, одни тэги вложены в другие.
<div class="me">
<h2 class="vacy" id="gdsfg">12</h2>
<span>Lorem <a href="#">ipsum</a> dolor sit amet <b>consectetur</b> adipisicing elit. A, earum itaque hic enim dicta quae. Doloremque officia quibusdam ut, a ratione totam repellendus ipsam, at dolorum iusto consequatur dolores fuga!</span>
</div>
Например тут в тэг <div> вложены <h2> и <span>, а внутри <span> находятся уже <a>, <b>. При чем <h2> и <span> находятся на первом уровне вложенности (являются детьми), а <a> и <b> на 2-м уровне (внуки). Получается некая иерархия. Это хорошо видно при просмотре через devtools.
Поиск элементов
Поиск 1 элемента
После того, как мы с ��ами получили объект BeautifulSoup, мы можем оттуда извлекать конкретные тэги. Самый простой вариант - это просто указать название тэга. В этом случае вернётся первый найденный результат. Если такого тэга на странице нет, то нам вернётся None.
Поиск по тэгу. Найдём заголовок <h1> на странице.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.content
soup = BeautifulSoup(tree, 'lxml')
header = soup.h1 # получаем объект Tag
print(header)
Отмечу, что в результате выполнения этого действия нам возвращается объект Tag. Раз это объект, у него есть свойства и методы, и мы можем с ним поработать. Например, можно получить текст элемента или значение конкретного атрибута. Но об этом позже.
Давайте теперь попробуем запросить несуществующий тэг и убедимся, что нам вернётся None.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header = soup.h6 # получаем None, т.к. тэга <h6> на указанной странице нет
if header is None: print('Элемент не найден')
Указанный выше способ прост, но не эффективен. Рассмотрим другие методы поиска HTML тэгов.
Поиск по тэгу и его атрибутам. С помощью метода find() можно задавать не просто название тэга, но и его атрибуты (вместе со значением). Данный метод возвращает первый найденный результат, а если ничего не найдено, то вернёт None.
Отмечу, что ищется именно точное совпадение.
Давайте найдем заголовок <h2> с атрибутом id="additionalinfo".
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header_addinitional_info = soup.find('h2', id='additionalinfo')
print(header_addinitional_info)
Вы можете искать сразу по нескольким значениям атрибута. Передаем их в виде списка. В примере ниже мы ищем <h2> у которого id может быть или add или info или additionalinfo.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header_addinitional_info = soup.find('h2', id=['add', 'info', 'additionalinfo'])
print(header_addinitional_info)
Также мы можем уточнить наш поиск. Давайте найдём тэг <span>, у которого id="special-text" и style="color: blue;" (если какое-то из условий не совпадёт, вернётся None).
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
unique = soup.find('span', style='color: blue;', id='special-text')
print(unique)
Или передаем их в виде словаря (код ниже аналогичен предыдущему).
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
unique = soup.find('span', attrs={'style':'color: blue;', 'id':'special-text'})
print(unique)
Мы можем указать несколько тэгов в виде списка. Давайте скажем, что нам подходит или тэг <div> или тэг <span> с id="special-text".
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
unique = soup.find(['div', 'span'], id='special-text')
print(unique)
Можно и вовсе не указывать название тэга. В примере ниже будет найден элемент с id="special-text" (вне зависимости у какого тэга этот атрибут).
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
unique = soup.find(id='special-text')
print(unique)
Также у нас есть возможность искать по тексту. Для этого используем атрибут text. Поиск идет по точному совпадению.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
unique = soup.find('span', text='уникальным идентификатором')
print(unique)
Отдельно нужно поговорить про атрибут class. Дело в том, что слово class является зарезервированным в python, поэтому если нам нужно по нему искать, то мы прописываем его с нижним подчеркиванием.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
footer = soup.find('div', class_='content-section') # когда ищем по class добавляем _
print(footer)
Кр��ме того иногда class (на странице) может содержать несколько значений через пробел. Например в примере ниже у тэга <div> class имеет сразу 3 значения: content-section, content и cont.
<div class="content-section content cont">
Мы можем искать по любому из этих значений, не обязательно указывать все 3.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
footer_div = soup.find('div', class_='cont')
print(footer_div)
Поиск с использованием регулярок. Ещё одним продвинутым методом поиска является использование регулярных выражений. В примере ниже мы ищем <span>, у которого id начинается с spec.
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find('span', id=re.compile('spec*'))
print(span)
Поиск по css селекторам. Также хорошим способом поиска будет использование css селекторов. В этом случае вместо метода find() нам понадобится метод select_one(). По css селекторам также есть отдельный материал.
Найдём тэг <h2> с id="additionalinfo".
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.select_one('h2[id="additionalinfo"]')
print(span)
Поиск с использованием lambda.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
example_1 = soup.find(lambda tag: tag.has_attr('class') and 'header' in tag['id']) # любой тэг у которого есть class и есть "header" в id.
print(example_1)
example_2 = soup.find(lambda tag: tag.name=="td" and 'гипертекст' in tag.text) # поиск по части текста.
print(example_2)
Поиск всех совпадений
В примерах выше мы с вами всегда получали одно совпадение, которое встречается самым первым на странице. Но у нас также есть возможность получить сразу все найденные совпадения в виде списка.
Для этого мы воспользуемся методами find_all() для поиска по атрибутам и select() для поиска по css селекторам. Все остальные "фишки" поиска аналогичны тем, что мы использовали выше.
Найдём все тэги <h2>.
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
headers = soup.find_all('h2')
# выведем все найденные совпадения
print(headers) # [<h2>О чем эта страница</h2>, <h2>Списки примеров</h2>, <h2>Пример таблицы</h2>, <h2 id="additionalinfo">Дополнительная информация</h2>]
# выведем только первое совпадение
print(headers[0])
Отмечу, что если даже будет найден только 1 элемент, он всё равно будет в списке, просто список будет из одного элемента. Если же совпадений не будет вовсе, то нам вернётся уже не None, а пустой список. Давайте в этом убедимся, попробовав отыскать несуществующий на странице тэг <h6>.
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
headers = soup.find_all('h6')
print(headers) # []
# проверить можно так
if headers:
print('нашли')
else:
print('ничего не найдено')
Мы можем указать, сколько именно совпадений нам нужно. Для этого прописываем параметр limit.
Давайте скажем, что мы хотим получить только первые два заголовка <h2>.
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
headers = soup.find_all('h2', limit=2)
# выведем первые два совпадения
print(headers) # [<h2>О чем эта страница</h2>, <h2>Списки примеров</h2>]
Пример поиска по css селектору.
import requests
from bs4 import BeautifulSoup
import re
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
headers = soup.select('h2')
print(headers)
Оси
Введение
Не всегда возможно найти конкретный тэг. способами выше. Что если у тэга вообще нет никаких атрибутов, неужели нам искать только по номеру?
На самом деле нет. Мы с вами можем зацепиться за какой-то другой тэг, а от него уже перейти к нужному. Рассмотрим как это сделать.
P.S. Названия осей я взял "неофициальные" (из xpath), не обессудьте.
Ось child
Ось child позволяет нам перейти к тэгу на 1 уровень ниже текущего. Проще говоря к ребенку. К примеру мы хотим отыскать вот этот абзац.
Как видим, у тэга <p> атрибутов нет, зато у его родителя (тэг <div>) есть class="footer". Значит мы сначала найдём этот тэг <div> с классом "footer", а затем уже найдем его ребенка (тэг <p>).
Для этого мы ещё раз вызовем метод find() с параметром recursive=False, чтобы поиск производился только по детям (не затрагивая других потомков - внуков, правнуков и т.д.).
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
footer_p = soup.find('div', class_='footer').find('p', recursive=False)
print(footer_p) # <p>© 2024 Пример HTML-страницы. Все права защищены.</p>
Напомню, что в этом случае нам вернётся первое найденное совпадение.
Чтобы получить все совпадения в виде списка, используйте метод find_all().
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
footer_p = soup.find('div', class_='footer').find_all('p', recursive=False)
print(footer_p) # [<p>© 2024 Пример HTML-страницы. <strong>Все</strong> права защищены.</p>, <p id="abc">Создано с помощью HTML и CSS</p>]
Ось parent
Если ось child позволяет нам опуститься на 1 уровень ниже, то ось parent наоборот подняться на уровень выше, к родителю. Для этого используется метод find_parent().
Давайте найдём <span> с id="special-text", а затем поднимемся к его родителю тэгу <p>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
text = soup.find('span', id="special-text").find_parent('p')
print(text)
find_parent() возвращает первое найденное совпадение. Для получения всех совпадений используйте метод find_parents().
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
text = soup.find('span', id="special-text").find_parents('p')
print(text) # тут уже будет список
Ось descendant
В этом случае мы будем искать не только среди потомков 1 уровня (детей), но и среди потомков всех остальных уровней (внуки, правнуки и т.д.).
Давайте на всякий случай повторим ещё раз.
В данном случае потомками 1-го уровня (детьми) для тэга <div> будут <h2>, <h3>, <ol>, <ul>. Тэг <li> же будет уже потомком 2-го уровня (внуком) для тэга <div>. В то же время для тэга <ol> тэг <li> будет потомком 1-го уровня (ребенком).
Окей, продолжим. Чтобы нам найти всех потомков мы вызываем метод find(), с параметром recursive=True (можно не прописывать, т.к. это идет значение по умолчанию).
Отыщем тэг <strong>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
li = soup.find('div', class_='content-section').find('strong')
# выведем первые два совпадения
print(li)
А теперь давайте попробуем найти <h3>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header = soup.find('div', class_='content-section').find('h3')
print(header) # None
Получаем None! Но почему? Помните, мы говорили, что метод find() берет первое найденное совпадение. Когда мы искали <div>, то он взял только первое совпадение, т.е. вот это.
А тут нет никакого <li>. Что же делать? Первый вариант - найти все совпадения методом find_all(), а далее перебрать их в цикле.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
content_section = soup.find_all('div', class_='content-section')
for content in content_section:
header = content.find('h3')
if header:
print(f'Нашли совпадение! {header}')
break
Второй вариант - использовать css селекторы.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
content_section = soup.select_one('div.content-section li:nth-child(1)')
print(content_section)
Ось ancestor
Ось ancestor ищет по всем предкам (на 1 уровень выше, на 2 и т.д.). Если find_parent() находил только родителя, то find_previous() будет искать также по дедушкам, прадедушкам и т.д.
Сейчас мы с вами сначала зацепимся за <span> с id="special-text", а затем от него найдём <div>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
div = soup.find('span', id='special-text').find_previous('div')
print(div)
Для получения всех совпадений используйте метод find_all_previous().
Ось next-sibling
Ось next-sibling позволяет искать среди элементов, которые находятся на этом же уровне после текущего. Можно сказать по младшим братьям или по соседним элементам.
Смотрите, вот тут <h2>, <p>, <p> все находятся на одном уровне. Мы можем найти этот <h2> по id, а затем с помощью оси next-sibling отыскать <p>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
text = soup.find('h2', id='additionalinfo').find_next_sibling('p')
print(text) # <p>Этот раздел содержит <strong>важный текст</strong> и демонстрирует использование различных атрибутов.</p>
Для поиска всех совпадений используйте find_next_siblings().
Ось previous-sibling
Эта ось аналогична предыдущей, но ищет уже по "старшим братьям".
Сейчас мы найдём тэг <p> с id="abc", а затем от него найдем его старшего брата <p>.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
text = soup.find('p', id='abc').find_previous_sibling('p')
print(text) # <p>© 2024 Пример HTML-страницы. Все права защищены.</p>
Свойства
Помимо описанных выше методов у нас также есть свойства. Во всех случаях (кроме parent, next, previous) возвращается итератор.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(class_='content-section cont')
childs = span.children # дети
parent = span.parent # родитель
parents = span.parents # отец|дед|прадед
desc = span.descendants # дети|внуки|правнуки
next_sibling = span.next_sibling # сосед
next_siblings = span.next_siblings # соседи (братья) ниже текущего
prev_sibling = span.previous_sibling # сосед (братья) выше текущего
prev_siblings = span.previous_siblings # соседи (братья) выше текущего
next = span.next # следующий
prev = span.previous # предыдущий
all_next = span.next_elements # все следующие
all_previous = span.previous_elements # все предыдущие
for x in childs:
if hasattr(x, 'get'):
print(x)
При использовании свойств надо отметить один важный момент. Поиск идет по всем узлам, доступным в BeautifulSoup - Tag, NavigableString, Comment. Т.е. помимо самого тэга также берется текст, комментарии, переносы строк.
Давайте посмотрим это на практике. Возьмем такую разметку и найдем <h2>.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2 class="heading">
<!--Комментарий-->
<a href="https://google.com">Незнакомцы. Глава 2(2025)</a>
<img src="/templates/blueshab/dleimages/no_icon.gif">
</h2>
</body>
</html>
from bs4 import BeautifulSoup
html = '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h2 class="heading"> <a href="https://google.com">Незнакомцы. Глава 2(2025)</a> <img src="/templates/blueshab/dleimages/no_icon.gif"> </h2> </body> </html>'
soup = BeautifulSoup(html, 'lxml')
div = soup.find('h2')
Теперь воспользуемся свойством children и посмотрим, что он нам найдёт.
from bs4 import BeautifulSoup
html = '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h2 class="heading"> <!--Комментарий--> <a href="https://google.com">Незнакомцы. Глава 2(2025)</a> <img src="/templates/blueshab/dleimages/no_icon.gif"> </h2> </body> </html>'
soup = BeautifulSoup(html, 'lxml')
div = soup.find('h2')
childrens = div.children
print(childrens.__next__()) #
print(childrens.__next__()) # <!--Комментарий-->
print(childrens.__next__()) #
print(childrens.__next__()) # <a href="https://google.com">Незнакомцы. Глава 2(2025)</a>
print(childrens.__next__()) #
print(childrens.__next__()) # <img src="/templates/blueshab/dleimages/no_icon.gif"/>
Обратите внимание, что первым элементом стал не <a>, а перенос строки. Это связано с тем, что между <h2> и <a> у нас есть пробел, а значит это текстовый узел, состоящий из одного пробела.
Потом уже идет комментарий, перенос строки, тэг <a>, потом снова текстовый узел (перенос строки), потом <img>.
Если бы в нашем html коде не было бы пробелов и переносов строк между тэгами, то результат был бы таким.
from bs4 import BeautifulSoup
html = '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h2 class="heading"><!--Комментарий--><a href="https://google.com">Незнакомцы. Глава 2(2025)</a><img src="/templates/blueshab/dleimages/no_icon.gif"></h2> </body> </html>'
soup = BeautifulSoup(html, 'lxml')
div = soup.find('h2')
childrens = div.children
print(childrens.__next__()) # <!--Комментарий-->
print(childrens.__next__()) # <a href="https://google.com">Незнакомцы. Глава 2(2025)</a>
print(childrens.__next__()) # <img src="/templates/blueshab/dleimages/no_icon.gif"/>
Получение значений
Итак, мы с вами научились находить элементы. Чаще всего нам возвращается объект Tag. Теперь научимся получать из элемента текст, значения атрибутов и сам элемент.
Для получения текста элемента можно использовать метод get_text().
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header = soup.h1 # получаем объект tag
text_header = header.get_text()
print(text_header) # An Interesting Title
Ещё одним способом получения текста элемента является атрибут .text. Результат не поменяется.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
header = soup.h1
text_header = header.text
print(text_header) # An Interesting Title
В чём же отличие? Если присмотреться, то мы увидим, что метод get_text() имеет некоторые необязательные параметры
Наиболее полезен тут strip=True, удаляющий лишние пробелы в начале и конце.
import requests
from bs4 import BeautifulSoup
html = '<div> Hello World ! </div>'
soup = BeautifulSoup(html, 'html.parser')
# Без обрезки
print(soup.get_text()) # ' Hello World ! '
# С обрезкой пробелов
print(soup.get_text(strip=True)) # 'Hello World !'
Как видите, в первом случае тэг <b> был просто откинут, при этом все пробелы исчезли. Во втором же случае мы явно указали, что хотим вставить пробел вместо тэга.
Помимо текстового содержимого, мы можем получить значения каких-то атрибутов.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(id='special-text')
span_id = span['style']
print(span_id) # color: blue;
Также можно воспользоваться методом get().
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(id='special-text')
span_id = span.get('style')
print(span_id) # color: blue;
Разница в том, что если указанного атрибута у элемента нет, то [''] выбросит исключение KeyError, а get() вернёт None. Также у get() можно передать второй параметр, который присвоит значение по умолчанию, если искомого атрибута у тэга нет.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(id='special-text')
try:
span_id = span['gg']
except KeyError as e:
print(f'Ошибка: {e}')
span_id = span.get('gg', 'нет атрибута') # 2-м параметром передали значение по умолч
print(span_id) # нет атрибута
Также существует свойство .attrs, возвращающее все атрибуты тэга.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(id='special-text')
attrs = span.attrs # вернёт словарь
# можно перебрать в цикле
for attr in attrs:
print(attr)
Свойство .name вернет имя тэга.
import requests
from bs4 import BeautifulSoup
response = requests.get('http://parsingme.ru/beautifulsoup/1.html')
tree = response.text
soup = BeautifulSoup(tree, 'lxml')
span = soup.find(id='special-text')
attrs = span.name # span
Спасибо всем, кто прочитал статью. Надеюсь, она была полезной. 1 февраля стартует мой курс по парсингу сайтов с помощью Python. Доступ к нему откроется на 7 дней. В курсе практика парсинга, ДЗ, поддержка в чате. Все, кто хочет залететь, пишите в тг - https://t.me/volody00