Сбор и обработка данных на Python: от парсинга до анализа

Этот курс научит вас эффективно собирать данные из различных источников, включая веб-сайты и API, используя современные инструменты Python. Вы освоите методы очистки, структурирования и предварительной обработки информации с помощью библиотек Pandas и NumPy для дальнейшего анализа.

1. Основы сбора данных: работа с HTTP-запросами, REST API и форматами JSON

Основы сбора данных: работа с HTTP-запросами, REST API и форматами JSON

Добро пожаловать на курс «Сбор и обработка данных на Python». Мы начинаем наше путешествие в мир Data Engineering и Data Science с самого фундаментального навыка — умения получать данные из интернета.

Представьте, что интернет — это огромный океан информации. Чтобы использовать эту воду для питья (анализа) или полива полей (обучения моделей), нам нужно построить трубопровод. В этой статье мы разберем, из чего состоят эти «трубы»: протокол HTTP, архитектурный стиль REST API и формат данных JSON.

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

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

Когда вы открываете браузер и вводите адрес сайта, происходит следующее:

  • Клиент (ваш браузер или скрипт на Python) формирует сообщение — запрос (Request).
  • Это сообщение летит через сеть к Серверу (мощному компьютеру, где хранятся данные).
  • Сервер обрабатывает запрос и отправляет обратно ответ (Response).
  • !Упрощенная схема обмена данными между клиентом и сервером.

    Язык, на котором общаются клиент и сервер, называется HTTP (HyperText Transfer Protocol).

    Анатомия HTTP-запроса

    HTTP-запрос — это не просто «дай мне страницу». Это структурированное сообщение, которое состоит из нескольких ключевых частей:

    * URL (Uniform Resource Locator): Адрес, куда мы стучимся. Например, https://api.github.com/users. * Метод (Method): Глагол, указывающий, что мы хотим сделать. * Заголовки (Headers): Служебная информация (какой у нас браузер, какой формат данных мы понимаем). * Тело (Body): Данные, которые мы передаем на сервер (используется не всегда).

    Основные методы HTTP

    В сборе данных мы чаще всего используем два метода:

  • GET — «Дай мне». Используется для получения данных. Когда вы открываете любую страницу в браузере, он делает GET-запрос. Тело запроса обычно пустое.
  • POST — «Возьми это». Используется для отправки данных на сервер (например, ввод логина и пароля или загрузка файла).
  • Существуют и другие методы (PUT, DELETE, PATCH), но на начальном этапе они встречаются реже.

    Коды состояния (Status Codes)

    Как понять, что ответил сервер? Для этого существуют трехзначные числа — коды состояния. Вы наверняка видели их раньше:

    * 200 OK: Всё отлично, запрос выполнен успешно. * 404 Not Found: Ресурс не найден (ошибка в адресе). * 403 Forbidden: Доступ запрещен (нужна авторизация). * 500 Internal Server Error: Проблема на стороне сервера (вы не виноваты).

    Практика: Библиотека requests в Python

    Python — идеальный язык для работы с сетью благодаря библиотеке requests. Она не входит в стандартную библиотеку, но является стандартом де-факто в индустрии.

    Установим её:

    Теперь попробуем сделать наш первый запрос к сайту GitHub:

    Объект response содержит всё, что вернул сервер: заголовки, статус и, самое главное, содержимое.

    Что такое API и REST?

    Если мы будем скачивать обычные HTML-страницы (как их видит человек), нам придется долго вычищать оттуда лишний мусор: теги верстки, стили, скрипты. Это называется парсинг HTML, и мы займемся этим в следующих статьях.

    Но программисты придумали способ, как программам общаться друг с другом напрямую, без визуальной шелухи. Это называется API (Application Programming Interface).

    > API — это интерфейс, который позволяет одной программе использовать функции другой программы.

    Представьте ресторан: * Вы — это Клиент (программа). * Кухня — это Сервер (база данных и логика). * Меню — это документация API. * Официант — это API.

    Вы не идете на кухню сами. Вы говорите официанту (API) строго по меню: «Хочу стейк». Официант уходит и возвращает вам готовое блюдо.

    !Метафора работы API: Официант как посредник между клиентом и кухней.

    REST (Representational State Transfer)

    REST — это набор правил (архитектурный стиль) того, как должен выглядеть «правильный» API.

    Основные принципы REST для нас как для сборщиков данных:

  • Клиент-сервер: Разделение ответственности.
  • Stateless (Без состояния): Сервер не запоминает нас между запросами. Каждый запрос должен содержать всю необходимую информацию (например, ключ доступа).
  • Единообразие интерфейса: Мы обращаемся к ресурсам по понятным адресам. Например, /users вернет список пользователей, а /users/1 — конкретного пользователя с ID 1.
  • Формат JSON: Язык данных

    Когда API возвращает нам данные, они чаще всего приходят в формате JSON (JavaScript Object Notation). Несмотря на название, он прекрасно работает с Python.

    JSON выглядит почти как словарь (dictionary) в Python. Это текстовый формат, который легко читают и люди, и машины.

    Пример JSON:

    Обратите внимание на отличия от Python: * true пишется с маленькой буквы (в Python True). * null вместо None. * Кавычки всегда двойные ".

    Работа с JSON в Python

    Библиотека requests умеет автоматически превращать ответ сервера из формата JSON в словарь Python. Для этого используется метод .json().

    Рассмотрим пример работы с реальным тестовым API — JSONPlaceholder. Это сервис, который имитирует базу данных постов блога.

    Результат выполнения:

    Мы получили данные, и они уже готовы к анализу! Нам не пришлось искать текст внутри тегов <div> или <span>.

    Заголовки и притворство браузером

    Иногда серверы защищаются от скриптов. Если вы просто сделаете requests.get(), сервер увидит, что к нему стучится Python-скрипт (в заголовке User-Agent будет написано python-requests). Некоторые сайты блокируют такие запросы.

    Чтобы обойти это, мы можем подменить заголовки, притворившись обычным браузером:

    Теперь сервер думает, что мы — Google Chrome на Windows 10.

    Заключение

    Сегодня мы заложили фундамент для всего курса. Мы узнали:

  • Как работает HTTP (запросы и ответы).
  • Что такое REST API и почему это лучший друг аналитика данных.
  • Как использовать библиотеку requests для отправки запросов.
  • Как обрабатывать данные в формате JSON.
  • В следующих статьях мы углубимся в более сложные темы: научимся парсить обычные HTML-страницы, когда API недоступен, и работать с автоматизацией браузера через Selenium.

    2. Парсинг HTML-страниц: извлечение структурированной информации с помощью BeautifulSoup и lxml

    Парсинг HTML-страниц: извлечение структурированной информации с помощью BeautifulSoup и lxml

    В предыдущей статье мы обсуждали идеальный мир сбора данных: мир, где серверы любезно предоставляют нам информацию в чистом формате JSON через API. Мы сравнили это с заказом еды в ресторане, где официант (API) приносит именно то, что вы просили.

    Однако реальность Data Engineer часто напоминает не ресторан, а дикий лес. Данные есть, но они «растут» на деревьях, спрятаны в кустах или зарыты в землю. Они предназначены для глаз человека, а не для алгоритмов машины. Эти данные упакованы в HTML — язык разметки веб-страниц.

    Сегодня мы научимся превращать хаос HTML-кода в стройные таблицы данных. Этот процесс называется парсингом (или скрапингом).

    Понимание структуры веб-страницы: DOM

    Прежде чем доставать инструменты, нужно понять материал, с которым мы работаем. Веб-страница — это не просто текст. Это иерархическая структура, дерево объектов.

    Когда браузер получает HTML-код, он строит из него DOM (Document Object Model). Представьте это как генеалогическое древо:

    * Корневой элемент (<html>) — это прародитель. * У него есть дети: «голова» (<head>) и «тело» (<body>). * Внутри «тела» живут заголовки (<h1>), параграфы (<p>), списки (<ul>) и контейнеры (<div>).

    !Иерархическая структура HTML-документа, где каждый тег является вложенным элементом.

    Чтобы извлечь данные, нам нужно научиться навигации по этому дереву: «Найди мне все ссылки внутри третьего параграфа, который лежит в блоке с новостями».

    Инструментарий: BeautifulSoup и lxml

    Для работы с HTML в Python существуют два основных инструмента, которые часто используются в тандеме:

  • BeautifulSoup (bs4) — библиотека, которая делает процесс навигации по дереву DOM простым и интуитивным. Она «всеядна» и может переварить даже «ломаный» HTML с ошибками верстки.
  • lxml — это очень быстрый парсер, который умеет работать как с HTML, так и с XML. Часто его используют как «движок» внутри BeautifulSoup для ускорения работы.
  • Установим необходимые библиотеки:

    Обратите внимание: нам всё еще нужен requests (из прошлой лекции), чтобы скачать страницу, прежде чем начать её разбирать.

    Работа с BeautifulSoup

    Давайте представим, что мы скачали HTML-код простой страницы книжного магазина. Начнем с создания объекта «супа».

    Поиск элементов: методы .find() и .find_all()

    Это два самых важных метода в библиотеке.

  • .find(tag, attributes) — находит первый попавшийся элемент, удовлетворяющий условиям.
  • .find_all(tag, attributes) — находит все элементы и возвращает их в виде списка.
  • Примеры:

    Обратите внимание на аргумент class_. В Python слово class зарезервировано, поэтому в BeautifulSoup используется нижнее подчеркивание.

    Извлечение данных: Текст и Атрибуты

    Найти элемент — это полдела. Нам нужно достать из него информацию.

    * .text или .get_text() — возвращает текст, который находится внутри тегов (без самих тегов). * ['attribute_name'] или .get('attribute_name') — позволяет достать значение атрибута (например, ссылку href или картинку src).

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

    Если вы знакомы с веб-разработкой, вам будет удобнее использовать CSS-селекторы. Это мощный способ указывать путь к элементу.

    В BeautifulSoup для этого используется метод .select() (возвращает список) и .select_one() (возвращает один элемент).

    Основные правила CSS-селекторов: * tag — поиск по тегу (например, div). * .class — поиск по классу (например, .price). * #id — поиск по ID (например, #b1). * tag1 tag2 — поиск вложенных элементов (например, div.book p.title — найти параграф с классом title внутри div с классом book).

    Мощь XPath и библиотека lxml

    Иногда структура страницы настолько сложная, что обычных методов поиска недостаточно. Здесь на сцену выходит XPath (XML Path Language). Это язык запросов к элементам XML/HTML документа.

    BeautifulSoup не поддерживает XPath напрямую (хотя есть сторонние расширения), поэтому для сложных задач часто используют библиотеку lxml напрямую.

    Синтаксис XPath напоминает путь к файлу на компьютере: * / — прямой потомок (как / в пути к файлу). * // — любой потомок (искать везде внутри). * @ — обращение к атрибуту. * text() — обращение к тексту.

    Пример использования lxml с XPath:

    XPath позволяет делать очень точные выборки. Например, «найти вторую ссылку в таблице» или «найти кнопку, которая содержит текст 'Купить'».

    Полный цикл: от запроса до данных

    Давайте объединим знания из прошлой статьи (requests) и текущей (BeautifulSoup) в единый скрипт. Напишем парсер, который собирает цитаты с известного тренировочного сайта quotes.toscrape.com.

    Этот скрипт выполняет полный цикл работы Data Engineer на этапе сбора данных (Ingestion).

    Этика и ограничения

    Парсинг — мощный инструмент, но с большой силой приходит большая ответственность.

  • Не DDOS-те сайты. Если вы отправляете тысячи запросов в секунду, вы можете «уронить» чужой сервер. Используйте задержки (time.sleep()) между запросами.
  • Читайте robots.txt. У каждого сайта есть файл site.com/robots.txt, где прописаны правила для роботов. Если там написано Disallow: /private/, туда ходить нельзя.
  • User-Agent. Как мы обсуждали в прошлой статье, всегда представляйтесь браузером, но не используйте парсинг для вредоносных целей.
  • Заключение

    Мы научились извлекать данные из HTML-страниц, используя BeautifulSoup для простых задач и познакомились с мощью XPath через lxml. Теперь вы можете собирать данные с новостных порталов, интернет-магазинов и блогов.

    Однако, современный веб сложен. Многие сайты (например, YouTube или Aviasales) не отдают данные сразу в HTML. Они подгружают их динамически с помощью JavaScript уже после открытия страницы. Обычный requests + BeautifulSoup там увидит лишь пустой экран.

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

    3. Продвинутый скрейпинг: автоматизация браузера и работа с динамическим контентом через Selenium

    Продвинутый скрейпинг: автоматизация браузера и работа с динамическим контентом через Selenium

    В предыдущих статьях мы освоили два важных инструмента: библиотеку requests для получения данных и связку BeautifulSoup + lxml для их извлечения. Мы научились отправлять запросы официанту (API) и разбирать готовые блюда (HTML).

    Но что делать, если вы приходите в ресторан, а вместо еды вам приносят набор сырых ингредиентов и плитку, и говорят: «Готовьте сами»? Именно так работают современные динамические веб-сайты.

    Если вы попробуете скачать страницу YouTube или бесконечную ленту социальной сети с помощью обычного requests.get(), вы, скорее всего, получите почти пустой HTML-файл. Данных там нет — они подгружаются позже с помощью JavaScript.

    Сегодня мы научимся решать эту проблему с помощью Selenium — инструмента, который позволяет управлять браузером программно, притворяясь обычным пользователем.

    Проблема «Пустой тарелки»: Статика vs Динамика

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

    Server-Side Rendering (SSR)

    Это классический подход. Когда вы запрашиваете страницу, сервер собирает её целиком (вставляет текст в HTML-теги) и отправляет вам готовый документ. Именно с такими сайтами мы работали ранее. requests получает тот же HTML, что и вы видите в браузере.

    Client-Side Rendering (CSR)

    Это современный подход (React, Vue, Angular). Сервер отправляет вам пустой каркас страницы и скрипт JavaScript. Браузер запускает этот скрипт, который стучится за данными на сервер и «рисует» контент прямо у вас на глазах.

    !Сравнение рендеринга на стороне сервера и на стороне клиента.

    Для Python-скрипта на requests такой сайт выглядит пустым, потому что requests не умеет выполнять JavaScript. Он просто скачивает текст и останавливается.

    Что такое Selenium?

    Selenium — это инструмент для автоматизации действий веб-браузера. Изначально он был создан для тестировщиков, чтобы проверять, как работают кнопки и формы на сайте. Но Data Engineers быстро поняли: если инструмент может нажимать кнопки и видеть результат, значит, он может и собирать данные.

    Selenium запускает настоящий браузер (Chrome, Firefox), загружает страницу, ждет выполнения всех скриптов, и только потом позволяет нам забрать данные.

    Установка

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

    Первый запуск: Hello, Robot!

    Давайте напишем скрипт, который просто откроет браузер и перейдет на сайт. Мы будем использовать Google Chrome.

    Когда вы запустите этот код, вы увидите магию: откроется отдельное окно Chrome, в котором будет написано «Браузером управляет автоматизированное ПО», сайт загрузится, а затем окно закроется.

    Поиск элементов: Локаторы

    В Selenium, как и в BeautifulSoup, нам нужно искать элементы на странице. Для этого используется класс By.

    Основные стратегии поиска: * By.ID — поиск по атрибуту id (самый быстрый и надежный). * By.CSS_SELECTOR — поиск по CSS-селекторам (как в soup.select()). * By.XPATH — поиск по XPath (как в lxml). * By.CLASS_NAME — поиск по классу.

    Синтаксис выглядит так:

    Взаимодействие с элементами

    Самое интересное в Selenium — это возможность взаимодействовать со страницей. Мы можем кликать, писать текст и скроллить.

    Представим, что нам нужно найти что-то на сайте Python.org:

    После выполнения этого кода браузер реально выполнит поиск и загрузит страницу с результатами.

    Искусство ожидания: Waits

    Это самая важная часть работы с Selenium.

    Динамические сайты не загружаются мгновенно. Если вы скажете драйверу «Нажми кнопку» сразу после driver.get(), скрипт упадет с ошибкой NoSuchElementException, потому что кнопка еще не успела отрисоваться.

    Новички часто используют time.sleep(5), просто останавливая скрипт. Это плохая практика:

  • Если сайт загрузился за 1 секунду, вы теряете 4 секунды впустую.
  • Если сайт загружается 6 секунд, скрипт упадет.
  • Правильный подход — Явные ожидания (Explicit Waits). Мы говорим драйверу: «Жди до 10 секунд, пока кнопка не станет кликабельной».

    Основные условия ожидания (expected_conditions): * presence_of_element_located — элемент появился в коде. * visibility_of_element_located — элемент виден глазу (не скрыт). * element_to_be_clickable — элемент готов к клику.

    Headless Mode: Работаем без интерфейса

    Когда вы отлаживаете скрипт, удобно видеть открывающийся браузер. Но когда скрипт работает на сервере, графический интерфейс не нужен и потребляет лишние ресурсы. Для этого существует Headless режим (безголовый).

    Теперь браузер работает в фоне, невидимо для вас.

    Пример: Скрейпинг динамического контента

    Давайте соберем всё вместе. Представим сайт с цитатами, где новые цитаты появляются только после прокрутки или нажатия кнопки (JS-генерация).

    Алгоритм действий:

  • Запускаем драйвер.
  • Открываем страницу.
  • Ждем загрузки контента.
  • Забираем HTML страницы.
  • Передаем HTML в BeautifulSoup (да, их можно комбинировать!).
  • Почему мы передаем HTML в BeautifulSoup, а не парсим через Selenium? Потому что BeautifulSoup работает с текстом и делает это в сотни раз быстрее, чем Selenium, который обращается к объектам браузера.

    Плюсы и минусы Selenium

    Плюсы: * Универсальность: Может собрать данные с любого сайта, который открывается в браузере. * Имитация человека: Сложнее заблокировать, так как поведение похоже на реального пользователя. * Визуализация: Легко отлаживать, так как видно процесс.

    Минусы: * Скорость: Это очень медленно. Запуск браузера и рендеринг страницы занимают секунды, тогда как requests справляется за миллисекунды. * Ресурсоемкость: Chrome потребляет много оперативной памяти.

    Заключение

    Selenium — это «тяжелая артиллерия» в мире сбора данных. Его стоит использовать только тогда, когда более легкие методы (requests, API) не работают из-за сложного JavaScript или защиты сайта.

    Мы научились:

  • Запускать автоматизированный браузер.
  • Искать элементы через By.
  • Взаимодействовать с формами и кнопками.
  • Правильно ждать загрузки элементов через WebDriverWait.
  • В следующей статье мы поговорим о том, как хранить собранные данные: от простых CSV файлов до баз данных SQL и NoSQL.

    4. Обработка и очистка данных: манипуляции с DataFrame и работа с пропусками в Pandas

    Обработка и очистка данных: манипуляции с DataFrame и работа с пропусками в Pandas

    Поздравляю! В предыдущих модулях мы научились добывать «цифровую руду»: скачивать HTML-страницы, обходить защиты сайтов и извлекать сырую информацию с помощью BeautifulSoup и Selenium. Но, как и настоящая руда, эти данные редко бывают чистыми. Они содержат «пустую породу» (пропуски), «примеси» (лишние символы валют, пробелы) и имеют неправильную форму (строки вместо чисел).

    Сегодня мы переходим от Data Engineering к Data Analysis. Мы познакомимся с библиотекой Pandas — швейцарским ножом для работы с табличными данными в Python. Наша цель — превратить хаотичный список словарей, полученный после парсинга, в стройный и чистый аналитический отчет.

    Знакомство с Pandas: Excel на стероидах

    Представьте Excel, но без графического интерфейса, зато с возможностью обрабатывать миллионы строк за секунды и автоматизировать любые действия. Это и есть Pandas.

    Основной строительный блок Pandas — это DataFrame (датафрейм). Это таблица, где:

  • Rows (Строки) — это ваши наблюдения (например, конкретные книги или товары).
  • Columns (Колонки) — это признаки (название, цена, рейтинг).
  • Index (Индекс) — это уникальный адрес каждой строки (по умолчанию просто порядковый номер).
  • !Структура DataFrame: Индекс, Колонки и Данные.

    Установка и импорт

    Pandas не входит в стандартную библиотеку Python, поэтому его нужно установить:

    В коде его принято импортировать под псевдонимом pd:

    Создание DataFrame из результатов парсинга

    Вспомним, что после парсинга (например, книжного магазина) мы обычно получаем список словарей. Давайте превратим его в DataFrame.

    Результат будет выглядеть как аккуратная таблица. Метод .head() — ваш лучший друг для быстрого осмотра данных.

    Первичный осмотр и диагностика

    Прежде чем что-то менять, нужно понять «диагноз» наших данных. Для этого есть метод .info().

    Вывод покажет:

  • Количество строк (RangeIndex).
  • Имена колонок.
  • Количество непустых (non-null) значений.
  • Тип данных в каждой колонке (int64 — целые числа, object — строки или смешанные типы, float64 — дробные числа).
  • Частая проблема парсинга: числа сохраняются как строки (тип object). Например, цена «500 руб.» для компьютера — это просто текст, с которым нельзя производить математические операции.

    Манипуляции с данными: выбор и фильтрация

    Чтобы работать с данными, нужно уметь доставать конкретные куски таблицы.

    Выбор колонок

    Если нам нужен только один столбец, мы обращаемся к нему как к ключу словаря. Это вернет объект Series (одна колонка).

    Выбор строк и ячеек: loc и iloc

    Это два основных инструмента навигации:

  • .loc — работает по меткам (названиям). Если индекс — это числа, то по числам. Если индекс — даты, то по датам.
  • .iloc — работает строго по позиции (порядковому номеру), как обычные списки Python (от 0 до N).
  • Фильтрация (Boolean Indexing)

    Допустим, мы хотим найти все книги, где больше 400 страниц. Но пока мы не можем этого сделать, так как в колонке pages есть пропуски, а price — вообще строки. Сначала нужно почистить данные.

    Очистка данных: работа с типами

    Посмотрите на колонку price. Там написано «500 руб.». Нам нужно убрать « руб.» и превратить текст в число.

    В Pandas для работы со строками есть специальный аксессор .str.

    Теперь price имеет тип float64. Мы можем считать среднюю цену, сумму и строить графики.

    Работа с пропусками (Missing Values)

    В реальном мире данные теряются. Сервер не отдал цену, верстка поехала, или товара нет в наличии. В Pandas отсутствие данных обозначается как NaN (Not a Number) для чисел или None для объектов.

    Обнаружение пропусков

    Метод .isna() (или .isnull()) возвращает таблицу из True и False, где True — это пропуск.

    Стратегия 1: Удаление (dropna)

    Самый простой способ — выкинуть испорченные данные. Если у книги нет цены, возможно, она нам не нужна для анализа выручки.

    > Важно: Удаление данных — это потеря информации. Если у вас всего 100 строк и в 50 из них есть пропуски, dropna() уничтожит половину вашего датасета.

    Стратегия 2: Заполнение (fillna)

    Более мягкий подход — заполнить пустоты разумным значением. Это называется импутация.

    Чем заполнять? * Константой: Например, 0 (если пропущено количество продаж). * Средним или медианой: Если пропущен возраст или цена. * Соседним значением: Актуально для временных рядов (курсы валют).

    Рассмотрим математическую формулу для заполнения средним значением. Мы вычисляем среднее арифметическое :

    Где — среднее значение, — количество существующих (не пустых) значений, а — каждое конкретное значение в колонке.

    Применим это на практике для колонки pages (количество страниц):

    Теперь наш датасет полон, и мы можем применять фильтры.

    Добавление новых данных (Feature Engineering)

    Часто нам нужно создать новые колонки на основе старых. Например, мы хотим узнать цену одной страницы книги.

    Это одна из главных фишек Pandas: вам не нужно писать циклы for для прохода по строкам. Вы пишете формулу столбец_А / столбец_Б, и Pandas делает это для тысяч строк мгновенно.

    Сохранение результатов

    После того как данные очищены, пропуски заполнены, а типы приведены в порядок, результат нужно сохранить. Pandas поддерживает десятки форматов.

    Заключение

    Сегодня мы прошли путь от «сырого» списка словарей до чистого, обогащенного датасета. Мы научились:

  • Создавать DataFrame.
  • Использовать loc и iloc для навигации.
  • Очищать строки и менять типы данных.
  • Находить и обрабатывать пропуски (NaN) методами dropna и fillna.
  • Теперь ваши данные готовы к самому интересному этапу — глубокому анализу и визуализации, о чем мы поговорим в следующих статьях курса.

    5. Хранение и экспорт: взаимодействие с SQL-базами данных и сохранение результатов в файлы

    Хранение и экспорт: взаимодействие с SQL-базами данных и сохранение результатов в файлы

    Мы прошли долгий путь. Мы научились отправлять запросы к серверам, парсить HTML-код, автоматизировать браузеры и очищать данные с помощью Pandas. Теперь у нас есть идеальный, чистый DataFrame, полный ценной информации. Но есть проблема: этот DataFrame живет только в оперативной памяти вашего компьютера. Как только вы закроете скрипт или выключите ноутбук, все данные исчезнут.

    Чтобы наш труд не пропал даром, данные нужно персистировать — то есть сохранить на жесткий диск или в удаленное хранилище. В этой статье мы разберем два основных пути сохранения данных: экспорт в файлы (CSV, Excel, JSON) и запись в базы данных SQL.

    Экспорт в файлы: просто и доступно

    Самый простой способ сохранить данные — записать их в файл. Pandas поддерживает множество форматов «из коробки», и методы для сохранения обычно начинаются с приставки .to_.

    !Схема экспорта данных из Pandas DataFrame в различные форматы хранения.

    CSV (Comma-Separated Values)

    Это «золотой стандарт» обмена табличными данными. CSV — это простой текстовый файл, где значения разделены запятыми (или точками с запятой). Его можно открыть в Блокноте, Excel, Google Sheets и любой другой программе для работы с данными.

    Почему важен index=False? По умолчанию Pandas сохраняет индекс (номера строк 0, 1, 2...) как отдельную колонку. Если вы потом снова загрузите этот файл, у вас появится лишняя колонка Unnamed: 0. Параметр index=False предотвращает это, сохраняя только ваши данные.

    Excel (XLSX)

    Если конечный потребитель ваших данных — менеджер или бухгалтер, ему удобнее получить готовый Excel-файл, а не «сырой» CSV.

    JSON

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

    Ограничения файлов

    Файлы отлично подходят для небольших проектов и разовых выгрузок. Но у них есть недостатки:

  • Сложность обновления: Чтобы добавить одну новую книгу, нужно перезаписывать весь файл или придумывать сложные механизмы дозаписи.
  • Отсутствие связей: Файлы не знают друг о друге. Вы не можете легко соединить данные о книгах из одного файла с данными о продажах из другого.
  • Производительность: Если у вас миллион строк, Excel может просто не открыться, а поиск по CSV будет очень медленным.
  • Здесь на сцену выходят Базы Данных (БД).

    Введение в SQL и реляционные базы данных

    SQL (Structured Query Language) — это язык для общения с базами данных. База данных похожа на умное хранилище, которое умеет не только хранить таблицы, но и быстро искать в них информацию, соединять их между собой и следить за целостностью данных.

    Мы будем использовать SQLite. Это самая простая SQL-база данных в мире. Ей не нужен сервер, логин или пароль. Вся база данных хранится в одном обычном файле на вашем компьютере, но работать с ней можно как с настоящей взрослой системой.

    SQLAlchemy: Мост между Python и SQL

    Чтобы Pandas мог общаться с базой данных, нам нужен посредник. В мире Python стандартом является библиотека SQLAlchemy. Она работает как переводчик: берет объекты Python и превращает их в SQL-команды.

    Установим её:

    Практика: Запись DataFrame в базу данных

    Процесс работы с БД всегда начинается с создания «движка» (engine). Это объект, который знает, где лежит база и как к ней подключиться.

    Теперь, когда у нас есть engine, мы можем использовать мощный метод Pandas — .to_sql().

    Параметр if_exists

    Это самый важный аргумент метода .to_sql(). У него есть три режима:

  • 'fail' (по умолчанию): Если таблица уже существует, Python выдаст ошибку и ничего не сделает. Это защита от случайной потери данных.
  • 'replace': Старая таблица будет удалена, а на её месте создана новая. Опасно, но удобно при полной перезагрузке данных.
  • 'append': Новые данные будут добавлены в конец существующей таблицы. Идеально для сбора данных, который запускается каждый день (например, сбор курсов валют).
  • Чтение данных из SQL

    Представьте, что прошло время, и нам нужно проанализировать накопленные данные. Нам не нужно открывать файл базы данных вручную. Pandas умеет читать прямо из SQL, используя метод .read_sql().

    Но сила SQL в том, что мы можем загружать не всё, а только то, что нам нужно. Мы можем написать SQL-запрос прямо внутри Python-кода.

    Это колоссально экономит память. Если в базе лежит 10 миллионов строк, а вам нужна только тысяча, вы загрузите в оперативную память только эту тысячу.

    Масштабируемость: от SQLite к PostgreSQL

    Самое прекрасное в использовании SQLAlchemy — это универсальность. Если завтра ваш проект вырастет и вам понадобится мощная серверная база данных вроде PostgreSQL или MySQL, вам почти не придется менять код.

    Вам нужно будет только изменить строку подключения при создании engine:

    Было (SQLite):

    Стало (PostgreSQL):

    Весь остальной код — to_sql, read_sql, работа с DataFrame — останется прежним. Это делает ваши навыки универсальными.

    Резюме курса

    В этой серии статей мы прошли полный цикл Data Engineering:

  • Сбор (Ingestion): Мы научились делать HTTP-запросы и работать с API.
  • Извлечение (Extraction): Мы освоили парсинг HTML с BeautifulSoup и автоматизацию с Selenium.
  • Обработка (Transformation): Мы использовали Pandas для очистки данных, работы с пропусками и типами.
  • Загрузка (Load): Сегодня мы научились сохранять результаты в файлы и базы данных.
  • Теперь у вас есть полный набор инструментов для создания собственных роботов-сборщиков данных и аналитических систем. Мир данных открыт для вас!