Извлечение текста, ссылок, атрибутов в BeautifulSoup

Извлечение текста, ссылок, атрибутов в BeautifulSoup Парсинг (BeautifulSoup, Selenium)

Важное предупреждение !!!

Данная статья носит исключительно информационный и образовательный характер. Она не является юридической консультацией и не может использоваться как руководство к действию в вопросах, связанных с парсингом, сбором данных и соблюдением законодательства.

Все примеры и рекомендации приведены для ознакомления с технической стороной процесса. Решение о законности парсинга в каждом конкретном случае зависит от множества факторов: юрисдикции, содержания сайта, способа сбора данных и целей использования информации. Для получения юридически обоснованного ответа обращайтесь к квалифицированным специалистам.

Перед началом прочтения статьи, ОБЯЗАТЕЛЬНО ознакомтесь со статьей «Что такое парсинг сайтов: законно ли это?«

Автор и администрация сайта не несут ответственности за использование материалов данной статьи в коммерческих или иных целях, а также за любые последствия, связанные с применением описанных методов.

Привет! Мы уже умеем находить элементы на странице. Теперь самое интересное — извлекать из них данные: текст, ссылки, изображения, любые атрибуты.

В этой статье мы разберём:

  • Извлечение текста из элементов
  • Получение ссылок (href)
  • Получение изображений (src)
  • Извлечение любых атрибутов
  • Обработку нескольких элементов

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный BeautifulSoup (статья 2)
  • Знание методов find() и find_all() (статья 3)
  • Базовое понимание HTML

Совет: Извлечение данных — это ради чего мы парсим. Здесь начинается самое интересное.

Основная часть

Извлечение текста

Самый простой способ — использовать свойство .text.

from bs4 import BeautifulSoup

html = """
<div class="article">
    <h1>Заголовок статьи</h1>
    <p>Первый абзац статьи. Здесь много интересного текста.</p>
    <p>Второй абзац с <a href="#">ссылкой</a> внутри.</p>
</div>
"""

soup = BeautifulSoup(html, "html.parser")

# Текст всего элемента
article = soup.find("div", class_="article")
print(article.text)

# Текст первого абзаца
first_p = soup.find("p")
print(first_p.text)   # Первый абзац статьи. Здесь много интересного текста.

Совет: .text и .get_text() — одно и то же.

print(article.get_text())   # То же самое

Очистка текста

Часто текст содержит лишние пробелы и переносы строк.

html = """
<div>
    <p>   Текст с пробелами   </p>
    <p>Строка 1
    Строка 2</p>
</div>
"""

soup = BeautifulSoup(html, "html.parser")

# Неочищенный текст
p = soup.find("p")
print(p.text)   # "   Текст с пробелами   "

# Очищенный текст
print(p.text.strip())   # "Текст с пробелами"

# Убираем лишние пробелы
text = " ".join(p.text.split())
print(text)   # "Текст с пробелами"

Совет: Всегда используй .strip() для удаления пробелов по краям.

Извлечение ссылок (href)

html = """
<div class="links">
    <a href="https://example.com">Example</a>
    <a href="https://google.com">Google</a>
    <a href="/about">О нас</a>
</div>
"""

soup = BeautifulSoup(html, "html.parser")

# Получение ссылки
link = soup.find("a")
href = link.get("href")
print(href)   # https://example.com

# Безопасное получение (если атрибута нет)
href = link.get("href", "")
print(href)

# Все ссылки
links = soup.find_all("a")
for link in links:
    print(link.get("href"))

Важно: Некоторые ссылки могут быть относительными (/about). Их нужно объединять с базовым URL.

import urllib.parse

base_url = "https://example.com"
href = "/about"
full_url = urllib.parse.urljoin(base_url, href)
print(full_url)   # https://example.com/about

Совет: Используй urljoin() для работы с относительными ссылками.

Извлечение изображений (src)

html = """
<div class="gallery">
    <img src="image1.jpg" alt="Картинка 1">
    <img src="image2.jpg" alt="Картинка 2">
    <img alt="Нет картинки">
</div>
"""

soup = BeautifulSoup(html, "html.parser")

# Получение src
img = soup.find("img")
src = img.get("src")
print(src)   # image1.jpg

# Все изображения
images = soup.find_all("img")
for img in images:
    src = img.get("src")
    alt = img.get("alt", "")
    if src:
        print(f"Ссылка: {src}, Alt: {alt}")

Совет: Всегда проверяй, что атрибут существует.

Извлечение произвольных атрибутов

html = """
<div data-id="123" data-category="tech" class="item">
    Товар
</div>
"""

soup = BeautifulSoup(html, "html.parser")
div = soup.find("div")

# Получение произвольных атрибутов
data_id = div.get("data-id")
data_category = div.get("data-category")
print(data_id)       # 123
print(data_category) # tech

# Все атрибуты
attrs = div.attrs
print(attrs)   # {'data-id': '123', 'data-category': 'tech', 'class': ['item']}

Обработка нескольких элементов

html = """
<ul>
    <li>Элемент 1</li>
    <li>Элемент 2</li>
    <li>Элемент 3</li>
</ul>
"""

soup = BeautifulSoup(html, "html.parser")

items = soup.find_all("li")
for item in items:
    print(item.text.strip())

# Сбор в список
texts = [item.text.strip() for item in items]
print(texts)   # ['Элемент 1', 'Элемент 2', 'Элемент 3']

Пример из реальной жизни

Парсинг статей с новостного сайта:

import requests
from bs4 import BeautifulSoup

url = "https://example-news.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")

articles = soup.find_all("article")

for article in articles:
    # Заголовок
    title_elem = article.find("h2")
    title = title_elem.text.strip() if title_elem else "Без заголовка"

    # Ссылка
    link_elem = article.find("a")
    link = link_elem.get("href") if link_elem else ""

    # Изображение
    img_elem = article.find("img")
    img = img_elem.get("src") if img_elem else ""

    # Текст
    text_elem = article.find("p")
    text = text_elem.text.strip() if text_elem else ""

    print(f"Заголовок: {title}")
    print(f"Ссылка: {link}")
    print(f"Изображение: {img}")
    print(f"Текст: {text[:50]}...")
    print("-" * 40)

Задачи для закрепления

Задача 1. Извлеки текст из первого абзаца страницы.

Задача 2. Получи все ссылки со страницы.

Задача 3. Получи все изображения и их alt-тексты.

Задача 4. Очисти текст от лишних пробелов и переносов строк.

Задача 5. Обработай относительные ссылки и преврати их в абсолютные.

Ответы:

Задача 1.

first_p = soup.find("p")
print(first_p.text.strip())

Задача 2.

links = soup.find_all("a")
for link in links:
    print(link.get("href"))

Задача 3.

images = soup.find_all("img")
for img in images:
    src = img.get("src")
    alt = img.get("alt", "")
    print(f"src: {src}, alt: {alt}")

Задача 4.

text = "   Текст с   пробелами  "
clean = " ".join(text.split())
print(clean)   # "Текст с пробелами"

Задача 5.

import urllib.parse
base = "https://example.com"
href = "/about"
full = urllib.parse.urljoin(base, href)
print(full)   # https://example.com/about

Нюансы и подводные камни

Пустые значения

# Без проверки
img = soup.find("img")
src = img.get("src")   # Если нет src, вернёт None

# С проверкой
img = soup.find("img")
src = img.get("src") if img else None

Ссылки без href

links = soup.find_all("a")
for link in links:
    href = link.get("href")
    if href:
        print(href)
    else:
        print("Ссылка без href")

Текст с дочерними элементами

.text извлекает весь текст, включая вложенные элементы.

html = "<p>Текст с <b>жирным</b> и <i>курсивом</i></p>"
soup = BeautifulSoup(html, "html.parser")
print(soup.text)   # Текст с жирным и курсивом

Частые ошибки и как их избежать

Ошибка 1: AttributeError при отсутствии атрибута

Используй .get() вместо прямого обращения.

Ошибка 2: Незакрытые теги

BeautifulSoup автоматически закрывает теги, но иногда лучше использовать html.parser или lxml.

Ошибка 3: Относительные ссылки

Используй urllib.parse.urljoin()

Шпаргалка

Что нужноКак пишется
Извлечь текстelement.text или element.get_text()
Очистить текстelement.text.strip()
Получить атрибутelement.get("src")
Получить hreflink.get("href")
Безопасное получениеelement.get("attr", "default")
Все атрибутыelement.attrs
Объединить ссылкиurllib.parse.urljoin(base, href)

Заключение / Выводы

Сегодня мы:

  • Научились извлекать текст
  • Получать ссылки (href)
  • Получать изображения (src)
  • Извлекать любые атрибуты
  • Очищать текст от мусора

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×