Структура HTML и DOM-дерево
HTML — это дерево вложенных тегов, и скрейпинг — это навигация по этому дереву.
HTML-документ — это иерархия элементов (тегов). Каждый тег может содержать атрибуты, текст и другие вложенные теги. Браузер и парсер строят из этой иерархии дерево — DOM.
Чтобы вытащить из страницы цену или заголовок, нужно понимать, где именно они лежат в структуре документа. HTML устроен как матрёшка: внешние теги содержат внутренние. Разберём простую страницу.
<html>
<body>
<div class="product">
<h2 class="title">Ноутбук Pro</h2>
<span class="price">79990</span>
<a href="/buy/123">Купить</a>
</div>
</body>
</html>Здесь div с классом product — контейнер. Внутри него — заголовок, цена и ссылка. Атрибут class="price" — это «адрес», по которому парсер найдёт цену. Атрибут href у ссылки хранит URL. Именно по тегам, классам и атрибутам скрейпер ориентируется на странице.
DOM-дерево
Парсер превращает плоский текст в дерево. Каждый тег — это узел; вложенные теги — его дети.
html
└── body
└── div.product
├── h2.title -> «Ноутбук Pro»
├── span.price -> «79990»
└── a[href=/buy/123] -> «Купить»Навигация по этому дереву — суть парсинга. «Найди div с классом product, внутри него возьми текст у span.price» — типичная инструкция скрейпера.
Как работает под капотом
В стандартной библиотеке Python есть модуль html.parser — простой потоковый парсер, который работает в браузере без установки чего-либо. Он не строит дерево сам, а вызывает методы-обработчики на каждый открывающий тег. Посмотрим, как он видит наш HTML:
Попробуй сам ▶
from html.parser import HTMLParser
page = '''
<div class="product">
<h2 class="title">Ноутбук Pro</h2>
<span class="price">79990</span>
<a href="/buy/123">Купить</a>
</div>
'''
class Reader(HTMLParser):
def handle_starttag(self, tag, attrs):
print('тег <%s> атрибуты: %s' % (tag, dict(attrs)))
def handle_data(self, data):
t = data.strip()
if t:
print(' текст:', t)
Reader().feed(page)Видно, как парсер по очереди встречает каждый тег, читает его атрибуты и текст. Высокоуровневые библиотеки вроде BeautifulSoup строят на этом удобное дерево с поиском — но принцип внутри тот же.
Атрибуты как опора скрейпера
Главная практическая ценность для скрейпера — атрибуты тегов. class и id придуманы для стилизации и скриптов, но именно они служат «адресами» при извлечении данных: верстальщик пометил цену классом price — и ты цепляешься за этот класс. Атрибуты data-* (например, data-product-id) часто хранят чистые машинные значения, удобнее видимого текста. А href и src несут ссылки и адреса картинок, которые нужны для обхода и скачивания.
Важно понимать, насколько разметка хрупка. Один и тот же текст можно сверстать десятком способов, и при редизайне классы меняются — поэтому скрейпер всегда чуть «привязан» к конкретной версии сайта и периодически ломается. Это нормально: устойчивость повышают, выбирая самые осмысленные и стабильные зацепки (семантические классы, id, data-*) и избегая привязки к позиции элемента. Хороший скрейпер пишут так, чтобы при поломке было легко понять, какой именно селектор «поехал», и быстро его поправить.
Частые ошибки
- Парсить HTML регулярками «вслепую». HTML вложенный и нерегулярный — для надёжного разбора нужен парсер дерева, а не только
re. - Привязываться к хрупким путям. Если зацепиться за «третий
divсверху», любой редизайн всё сломает. Лучше цепляться за классы и осмысленные атрибуты. - Забывать, что классов может быть несколько.
class="price big sale"— это три класса сразу.
Best practices
- Изучай структуру страницы через «Инспектор» в браузере (F12) перед написанием кода.
- Ищи устойчивые «зацепки»:
id, осмысленныеclass, атрибутыdata-*. - Для серьёзного разбора используй парсер дерева (BeautifulSoup, lxml), а не только регулярки.
Освой инспектор браузера как главный рабочий инструмент исследования страницы. По F12 открывается панель разработчика; во вкладке Elements можно навести курсор на любой кусок страницы и сразу увидеть его тег, классы и положение в дереве, а правый клик «Copy → Copy selector» подскажет готовый CSS-селектор. Это превращает написание скрейпера из угадывания в точную работу: ты буквально показываешь браузеру нужный элемент и читаешь его «адрес». Привычка сначала изучить структуру в инспекторе, а потом писать код экономит massу времени.
Итог: HTML — это дерево тегов с атрибутами. Скрейпинг сводится к навигации по этому дереву и извлечению текста и атрибутов из нужных узлов. Стандартный html.parser показывает механику изнутри.