1. Навігація по HTML-дереву
Сьогодні ми зануримося у загадковий світ HTML-дерев і навчимося витягувати інформацію з веб-сторінок як справжні програмістські ніндзя. Ми продовжимо використовувати магічну бібліотеку BeautifulSoup, щоб дістатися до потрібних даних і прикрасити наші вже доволі розумні скрипти ще більшою функціональністю. Тож змащуйте вашу клавіатуру, і почнемо!
Отже, перш ніж братися за витяг даних, давайте ще раз розберемося, що таке HTML-дерево. Уявіть собі це як велике сімейне дерево, де кожен тег - це окремий родич. Є батьки, діти, брати і сестри. Наші завдання - це знайти конкретних "родичів", щоб акуратно витягти з них цінні сімейні реліквії (або дані).
Ось так може виглядати шматок HTML:
<div class="article">
<h2 id="title">Заголовок</h2>
<p class="content">Це текст статті...</p>
<a href="https://example.com" class="link">Читати далі</a>
</div>
Тут у нас є div, який є батьківським елементом для h2, p, та a. Кожен з них має свої атрибути і вміст.
2. Витяг даних за тегами
BeautifulSoup пропонує зручні методи для навігації по дереву і витягу даних. Почнемо з базового методу find(), який дозволить нам знайти перший елемент із певним тегом. А ось find_all() - це як пошуковий бульдозер, який відкопує всі елементи із заданим тегом.
from bs4 import BeautifulSoup
html_doc = """<div class="article">
<h2 id="title">Заголовок</h2>
<p class="content">Це текст статті...</p>
<a href="https://example.com" class="link">Читати далі</a>
</div>"""
soup = BeautifulSoup(html_doc, 'html.parser')
# Знаходимо перший параграф
first_paragraph = soup.find('p')
print(first_paragraph.text) # Вивід: Це текст статті...
# Знаходимо всі посилання
all_links = soup.find_all('a')
for link in all_links:
print(link['href']) # Вивід: https://example.com
3. Використання атрибутів для фільтрації елементів
Тепер, коли ми освоїли пошук за тегами, час дізнатися, як фільтрувати елементи за допомогою атрибутів, таких як id і class. Ці атрибути — як закладки на сторінці, за якими одразу видно, що до чого.
<div class="article">
<h2 id="title">Заголовок</h2>
<p class="content">Це текст статті...</p>
<a href="https://example.com" class="link">Читати далі</a>
</div>
# Знаходимо елемент з певним id
title = soup.find(id="title")
print(title.text) # Вивід: Заголовок
# Знаходимо всі елементи з класом "content"
content_paragraphs = soup.find_all(class_="content")
for p in content_paragraphs:
print(p.text) # Вивід: Це текст статті...
Важливо! Ми використовуємо class_ замість class — це щоб уникнути конфлікту із зарезервованим словом Python.
4. Практика витягу даних із заданими умовами
А тепер перейдемо до практики! Уявіть, що вам потрібно витягнути посилання і тексти заголовків із великого повторюваного HTML-масиву статей. Ось приклад даних і як із ними працювати:
<div class="articles">
<div class="article">
<h2 class="title">Перша стаття</h2>
<a href="https://example.com/1" class="read-more">Читати далі</a>
</div>
<div class="article">
<h2 class="title">Друга стаття</h2>
<a href="https://example.com/2" class="read-more">Читати далі</a>
</div>
</div>
І ось як ми можемо витягти заголовки і посилання:
html_doc = """<div class="articles">
<div class="article">
<h2 class="title">Перша стаття</h2>
<a href="https://example.com/1" class="read-more">Читати далі</a>
</div>
<div class="article">
<h2 class="title">Друга стаття</h2>
<a href="https://example.com/2" class="read-more">Читати далі</a>
</div>
</div>"""
soup = BeautifulSoup(html_doc, 'html.parser')
articles = soup.find_all('div', class_='article')
for article in articles:
title = article.find('h2', class_='title').text
link = article.find('a', class_='read-more')['href']
print(f"Заголовок: {title}, Посилання: {link}")
# Вивід:
# Заголовок: Перша стаття, Посилання: https://example.com/1
# Заголовок: Друга стаття, Посилання: https://example.com/2
5. Про підводні камені
Тепер, коли ви озброєні знаннями, давайте поглянемо на деякі типові помилки. Одна із найпоширеніших проблем — це спроба доступу до атрибута, якого не існує. У такому випадку Python відповідає дружнім, але все ж неприємним KeyError. Щоб уникнути цього, можна застосовувати метод .get() для отримання атрибутів із дефолтним значенням, якщо вони відсутні.
Крім того, не забувайте про HTML-елементи, які можуть бути вкладеними і мати складну структуру. Використовуйте інструмент перегляду вихідного коду сторінки у браузері, щоб упевнитись, що ви правильно розумієте структуру, перш ніж намагатися витягти дані з допомогою BeautifulSoup.
Наступною зупинкою в нашій захопливій подорожі стане застосування CSS-селекторів, щоб ще точніше цілитись і витягати інформацію. Тож залишайтесь з нами, адже пригоди у світі BeautifulSoup тільки починаються!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ