Основы парсинга сайтов: от HTML до готового датасета для NLP. BeautifulSoup.. BeautifulSoup. HTML.. BeautifulSoup. HTML. nlp.. BeautifulSoup. HTML. nlp. playwright.. BeautifulSoup. HTML. nlp. playwright. python.. BeautifulSoup. HTML. nlp. playwright. python. requests.. BeautifulSoup. HTML. nlp. playwright. python. requests. датасет.. BeautifulSoup. HTML. nlp. playwright. python. requests. датасет. очистка данных.. BeautifulSoup. HTML. nlp. playwright. python. requests. датасет. очистка данных. парсинг сайтов.. BeautifulSoup. HTML. nlp. playwright. python. requests. датасет. очистка данных. парсинг сайтов. языковые модели.

Вы освоили машинное обучение, знаете, чем transformer отличается от LSTM, но где брать данные для своих проектов? Готовые датасеты — это хорошо, но они общие. А если вам нужны посты из конкретного Telegram‑канала, отзывы с узкопрофильного форума или корпус текстов по редкой теме?

Парсинг сайтов — это навык, который превращает интернет в вашу персональную фабрику данных. Без него даже самая умная модель останется без «топлива». В этой статье мы рассмотрим весь путь: от первого запроса к сайту до готового датасета, пригодного для обучения.

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

📍 Прежде чем переходить к практике, пройдите короткий бесплатный тест по NLP и языковым трансформерным моделям. Он поможет понять, в каких темах вы уже уверены, а что стоит подтянуть. ➞ Пройти тест

С чего всё начинается

Прежде чем писать код, нужно понять, как устроен веб. Представьте, что интернет — это огромная библиотека, а ваш браузер — библиотекарь, который ходит за книгами. Парсер — это робот‑библиотекарь, который делает это быстро и по заданному алгоритму.

Всё начинается с HTTP‑запроса. Когда вы вводите адрес сайта, ваш браузер отправляет серверу запрос: «Дай мне, пожалуйста, содержимое страницы». Сервер отвечает HTML‑кодом — это «скелет» страницы, размеченный тегами.

Пример простого HTML‑фрагмента:

<div class="product">
    <h2>Название товара</h2>
    <span class="price">1000 ₽</span>
    <p class="description">Описание товара...</p>
</div>

Парсер должен найти этот блок (div class="product") и извлечь из него нужные данные: заголовок (h2), цену (span.price) и описание (p.description).

GET и POST являются двумя основными типами запросов. GET используется для получения данных. Когда вы открываете страницу товара, браузер отправляет GET‑запрос. В свою очередь POST используется для отправки данных на сервер, например, при заполнении формы поиска или авторизации. На начальном этапе вам почти всегда будет достаточно GET‑запросов.

Requests + BeautifulSoup

Это стандартная связка для парсинга, известная как «золотая середина» для большинства задач, потому что requests скачивает страницу, а BeautifulSoup помогает находить в ней данные.

Почему они хороши вместе? Requests выступает в роли курьера, доставляя вам HTML‑код, а BeautifulSoup — в роли аналитика, который этот код изучает и находит в нём закономерности. requests идеально подходит для базовых HTTP‑операций, а BeautifulSoup — для навигации по HTML‑дереву и поиска элементов.

Для установки необходимо выполнить следующее:

pip install requests beautifulsoup4 lxml

Здесь lxml — это быстрый парсер, который мы передадим BeautifulSoup для ускорения работы. Теперь давайте напишем скрипт, который загружает страницу и извлекает заголовки статей.

import requests
from bs4 import BeautifulSoup

# 1. Отправляем GET-запрос к сайту
url = "https://example.com/blog"

# Для реальных проектов всегда указывайте User-Agent, чтобы не походить на бота
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)

# 2. Проверяем, успешно ли прошёл запрос (код 200 означает "OK")
if response.status_code == 200:
    # 3. Передаём HTML-код страницы BeautifulSoup для анализа
    soup = BeautifulSoup(response.text, 'lxml')

    # 4. Находим все элементы, содержащие заголовки.

    # Предположим, заголовки статей находятся в теге <h2> с классом "post-title"
    titles = soup.find_all('h2', class_='post-title')

    # 5. Извлекаем и выводим текст из каждого найденного элемента
    for title in titles:
        print(title.text.strip())
else:
    print(f"Ошибка загрузки страницы. Код: {response.status_code}")

Краткий разбор полётов:

  • requests.get(url, headers=headers) загружает страницу.

  • BeautifulSoup(response.text, 'lxml') создаёт объект, с которым удобно работать.

  • soup.find_all('h2', class_='post-title') ищет все теги <h2> с классом post-title. Это один из самых мощных методов библиотеки.

  • title.text.strip() достаёт текст внутри тега и удаляет лишние пробелы и переносы строк.

Продвинутый поиск: CSS‑селекторы

Метод find_all — это конечно хорошо, но иногда удобнее использовать CSS‑селекторы. Это мощный язык запросов к элементам HTML. Давайте посмотрим несколько примеров использования.

Найдем все ссылки внутри элементов с классом «product»

links = soup.select('.product a')

Теперь поищем элемент с id=«main-content»

main_content = soup.select_one('#main-content')

Найдем все изображения внутри блока с классом «gallery»

images = soup.select('.gallery img')

Метод .select() возвращает список всех подходящих элементов, а.select_one() — первый подходящий. Это делает код более читаемым, особенно при работе со сложной вложенностью.

Когда страницы оживают: Playwright для SPA и React‑сайтов

Современный интернет — это уже не просто набор HTML‑страниц. Многие сайты (особенно с технологиями React, Vue, Angular) — это одностраничные приложения (SPA). Они загружают пустой «скелет», а весь контент подтягивается скриптами уже после загрузки.

Вы можете получить HTML‑код такой страницы через requests, но красивого текста с данными в нём не будет. Вам нужен инструмент, который может не просто скачать файл, а запустить браузер и выполнить весь JavaScript‑код, как это делает обычный пользователь. И здесь на сцену выходит Playwright.

Playwright — это библиотека для автоматизации браузеров (Chrome, Firefox, Safari). Она запускает настоящее браузерное окно (или «голову», headless‑режим) и выполняет все действия, которые может делать человек: кликать, скроллить, вводить текст. После того как страница полностью загружена и все скрипты отработали, мы можем получить её финальный HTML‑код и спокойно распарсить его уже знакомым BeautifulSoup. Это незаменимый инструмент для сбора данных с SPA, сайтов с бесконечной прокруткой (infinite scroll) и для обхода несложной защиты от ботов.

Для установки выполним следующее:

pip install playwright

playwright install # Скачивает браузеры (chromium, firefox, webkit)

Далее рассмотрим пример скрипта для динамической страницы:

import asyncio
from playwright.async_api import async_playwright
from bs4 import BeautifulSoup
 
async def scrape_dynamic_site():
    async with async_playwright() as p:
        # Запускаем браузер (headless=False, чтобы увидеть окно браузера)
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        
        # Переходим на сайт и ждём, пока загрузится сеть (важно для SPA!)
        await page.goto("https://quotes.toscrape.com/scroll")
        await page.wait_for_load_state("networkidle")
        
        # Симулируем прокрутку вниз для подгрузки новых элементов (если нужно)
        for _ in range(3):
            await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
            await page.wait_for_timeout(1000)  # Ждём подгрузки
        
        # Получаем HTML-код полностью отрисованной страницы
        html = await page.content()
        
        # Закрываем браузер
        await browser.close()
        
        # Теперь можно парсить этот HTML через BeautifulSoup
        soup = BeautifulSoup(html, 'lxml')
        quotes = soup.select('.quote')
    
        for quote in quotes:
            text = quote.select_one('.text').text
            author = quote.select_one('.author').text
            print(f"{author} said: {text[:50]}...")

asyncio.run(scrape_dynamic_site())

В этом коде мы не просто скачиваем страницу, а эмулируем поведение пользователя: ждём загрузки, прокручиваем вниз, даём время подгрузиться новым элементам, и только потом забираем готовый HTML.

Пайплайн для качественного датасета

Получить сырой текст с сайта — это только полдела. Чтобы он превратился в полезный датасет для NLP, ему нужна обработка. Это похоже на добычу нефти: сначала идёт бурение (парсинг), а потом — сложная переработка (очистка), чтобы получить бензин (датасет).

Вот основные шаги по превращению «грязных» веб‑данных в пригодные для обучения модели:

  1. Извлечение (Extraction): Мы уже это умеем. Получаем HTML и вытаскиваем из него нужные поля (текст, даты, теги).

  2. Очистка (Cleaning): Удаляем HTML‑теги, которые могли остаться. Убираем мусор: специальные символы (&nbsp;, xa0, u200b), лишние пробелы и переносы строк.

  3. Нормализация (Normalization): Приводим текст к единому виду. Например, все даты приводим к формату ГГГГ‑ММ‑ДД, имена и названия очищаем от случайных символов.

Предобработка для NLP (Preprocessing): Этот шаг зависит от вашей задачи. Он может включать:

  • Токенизацию (разбиение на слова).

  • Удаление стоп‑слов (очень частых слов, не несущих смысла: «и», «в», «на»).

  • Лемматизацию или стемминг (приведение слов к начальной форме: «бежал», «бежит», «бегут» → «бежать»).

Теперь давайте рассмотрим пример кода, который дополняет наш пайплайн, превращая сырой HTML в чистый текст.

import re
import pandas as pd
from bs4 import BeautifulSoup
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer

# Не забудьте скачать ресурсы NLTK: nltk.download('stopwords'), nltk.download('wordnet')
lemmatizer = WordNetLemmatizer()
stop_words = set(stopwords.words('russian'))
 
def clean_text(html_content):
    # 1. Извлечение текста из HTML
    soup = BeautifulSoup(html_content, 'lxml')
    text = soup.get_text(separator=' ')
    
    # 2. Приведение к нижнему регистру и удаление спецсимволов
    text = text.lower()
    text = re.sub(r'[^а-яa-z0-9s]', '', text)  # Оставляем только буквы, цифры и пробелы
    
    # 3. Токенизация (разбиение на слова)
    tokens = text.split()
    
    # 4. Удаление стоп-слов и коротких слов
    tokens = [token for token in tokens if token not in stop_words and len(token) > 2]
    
    # 5. Лемматизация
    tokens = [lemmatizer.lemmatize(token) for token in tokens]
   
    # 6. Сборка обратно в строку
    clean_text = ' '.join(tokens)
    return clean_text

# Пример использования в вашем пайплайне
raw_data = []  # список словарей, полученных после парсинга

for item in raw_data:
    item['cleaned_content'] = clean_text(item['raw_html'])

df = pd.DataFrame(raw_data)
df.to_csv('my_dataset.csv', index=False)  # Сохраняем готовый датасет

Следуя этому пайплайну, вы превратите ворох сырых HTML‑страниц в структурированный, чистый датасет, готовый для обучения моделей классификации, генерации текста или построения RAG‑систем.

Заключение

Парсинг сайтов — это фундаментальный навык для любого специалиста по данным, который хочет работать с реальными, неигрушечными задачами. Мы прошли путь от базовых HTTP‑запросов до запуска браузеров и очистки данных. Теперь у вас есть инструментарий, чтобы создавать собственные датасеты для самых смелых NLP‑проектов.

Основы парсинга сайтов: от HTML до готового датасета для NLP - 1

Когда нужно не просто «поиграться с LLM», а встроить языковые модели в реальный продукт, быстро выясняется: базового понимания ChatGPT уже недостаточно. Нужно разбираться, как работают трансформеры, embeddings, RAG, тонкая настройка моделей и оценка качества, иначе проект легко превращается в набор красивых демо без стабильного результата.

Курс «Языковые трансформенные модели / NLP» помогает перейти от поверхностного использования нейросетей к инженерному пониманию NLP‑систем: как выбирать подходящую архитектуру, готовить данные, работать с текстовыми корпусами и собирать решения, которые можно применять в рабочих задачах.

Если вы уже пробовали работать с LLM, но хотите перейти от промптов и демо к более инженерному пониманию моделей, начните с бесплатного открытого урока:

20 мая в 20:00. «Основы парсинга сайтов».
Разберём, как с помощью Python скачивать информацию с сайтов, извлекать нужные данные и собирать основу для собственного датасета, который затем можно использовать в NLP‑задачах.

Полный список бесплатных уроков мая смотрите в дайджесте.

Автор: Andrey_Biryukov

Источник