JavaRush /Курси /Python SELF UA /Витяг даних зі складних HTML-структур

Витяг даних зі складних HTML-структур

Python SELF UA
Рівень 34 , Лекція 0
Відкрита

1. Основи роботи зі складними HTML-структурами

Перш ніж ми почнемо розбирати складні HTML-розмітки, важливо зрозуміти, чому HTML може бути настільки заплутаним. Веб-розробники часто використовують складні вкладені елементи для організації контенту, що може перетворитися на справжній жах для тих, хто намагається витягнути дані з таких сторінок. Але не переймайтесь — якщо у вас є хороший план і інструменти, ви впораєтесь без зайвих проблем!

Розбір HTML-дерева

Уявіть собі HTML-документ як дерево: кожен елемент — це вузол, який може містити текст або інші вузли. На вершині цього дерева стоїть html, за ним слідують head і body, а далі розташовуються різні дочірні елементи. Вкладені елементи знаходяться глибше в цьому дереві.

Приклад простої HTML-структури:

HTML

<html>
  <head>
    <title>Приклад</title>
  </head>
  <body>
    <div class="content">
      <h1>Заголовок</h1>
      <p>Параграф 1</p>
      <p>Параграф 2</p>
      <div class="nested">
        <ul>
          <li>Елемент 1</li>
          <li>Елемент 2</li>
          <li><span>Елемент 3</span></li>
        </ul>
      </div>
    </div>
  </body>
</html>

Як ви бачите, у нас є div з класом nested, який містить ul, а той, своєю чергою, наповнений li. Це приклад того, як можуть бути вкладені елементи.

2. BeautifulSoup для витягу даних

Витяг даних із вкладених елементів

Згадуємо, як працює BeautifulSoup. Давайте використаємо BeautifulSoup для отримання тексту зі списку li. Час стати справжнім детективом і зібрати дані з наших вкладених структур.

Python

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, 'html.parser')
nested_items = soup.select('.nested ul li')

for item in nested_items:
    print(item.get_text())

Результат:


Елемент 1
Елемент 2
Елемент 3

Як ви бачите, ми використали метод select з CSS-селектором для знаходження всіх li всередині елемента з класом nested. Метод get_text() дозволяє витягати текст безпосередньо з знайдених елементів.

3. Робота з багаторівневими елементами

Іноді дані знаходяться не тільки в глибині структури, але й розподілені за різними рівнями, що ускладнює задачу витягу. Давайте розберемося, як отримати дані з більш складного HTML-дерева.

Приклад складної структури:

HTML

<html>
  <body>
    <div class="wrapper">
      <div class="header">
        <h1>Це заголовок</h1>
      </div>
      <div class="content">
        <div class="article">
          <h2>Стаття 1</h2>
          <p>Зміст статті 1</p>
        </div>
        <div class="article">
          <h2>Стаття 2</h2>
          <p>Зміст статті 2</p>
        </div>
      </div>
      <div class="footer">
        <p>Контактна інформація</p>
      </div>
    </div>
  </body>
</html>

Витяг даних із рівнів

Тепер спробуємо витягти назви всіх статей та їхній зміст.

Python

articles = soup.select('.content .article')

for article in articles:
    title = article.find('h2').get_text()
    content = article.find('p').get_text()
    print(f'Заголовок: {title}')
    print(f'Зміст: {content}\n')

Очікуваний результат:


Заголовок: Стаття 1
Зміст: Зміст статті 1

Заголовок: Стаття 2
Зміст: Зміст статті 2

Ми використовуємо комбінацію методів select і find для досягнення наших цілей. select допомагає знайти батьківський елемент, а find витягує інформацію з дочірніх.

4. Особливості роботи з вкладеними елементами

Розглядаючи веб-сторінки, ви можете зіткнутися з такими проблемами, як наявність кількох вкладених елементів з однаковими класами або тегами. У таких випадках використання контекстного пошуку та чітка ідентифікація потрібних елементів допоможуть уникнути помилок.

Приклад складної вкладеності:

HTML

<html>
  <body>
    <div class="container">
      <div class="item">
        <h2>Номер 1</h2>
        <div class="details">Деталі 1</div>
      </div>
      <div class="item">
        <h2>Номер 2</h2>
        <div class="details">Деталі 2</div>
        <div class="additional">
          <div class="info">Додат. інформація</div>
        </div>
      </div>
    </div>
  </body>
</html>

Витяг даних з урахуванням вкладеності

Щоб уникнути плутанини, слід знаходити більш специфічні елементи:

Python

items = soup.select('.container .item')

for item in items:
    number = item.find('h2').get_text()
    details = item.select_one('.details').get_text()
    additional_info = item.select_one('.additional .info')
    
    print(f'Номер: {number}')
    print(f'Деталі: {details}')
    
    if additional_info:
        print(f'Додаткова інформація: {additional_info.get_text()}')
    print()

Тут ми використовуємо метод select_one, який повертає лише перший знайдений елемент, щоб уникнути дублювання даних із додаткових блоків.

5. Практичні аспекти та типові помилки

Під час роботи з складними HTML-структурами легко заплутатися або зіштовхнутися з помилками. Одна з типових помилок — це спроба доступу до неіснуючого елемента, що призводить до AttributeError. Щоб уникнути цього, завжди перевіряйте існування елемента перед тим, як працювати з ним.

Ще одна важлива річ — це розуміння того, що не завжди потрібно витягати дані одразу з наскоку. Іноді корисно зробити попередній розбір структури, використовувати відладочні виводи та перевіряти проміжні результати.

У реальних проєктах навички роботи з вкладеними HTML-структурами можуть бути критично важливі. Це застосовується не тільки у веб-скрепінгу, але й у тестуванні веб-інтерфейсів, автоматизації тестування та навіть у аналізі даних зі складних API, де вивід може мати форматований, вкладений відповідь.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ