Python для сбора и обработки данных: Интенсив для разработчиков

Курс предназначен для программистов, владеющих C++ и SQL, желающих быстро освоить Python для задач Data Engineering. Программа фокусируется на синтаксических особенностях языка, библиотеках для парсинга веб-ресурсов и инструментах первичного анализа данных.

1. Быстрый старт: Синтаксис Python, структуры данных и отличия от C++ и PHP

Быстрый старт: Синтаксис Python, структуры данных и отличия от C++ и PHP

Добро пожаловать в курс «Python для сбора и обработки данных». Поскольку вы уже владеете C++, PHP и SQL, мы пропустим объяснения того, что такое переменная или цикл. Ваша задача — перенести существующие ментальные модели на рельсы Python и понять, почему этот язык стал стандартом де-факто в мире Data Science.

В этой статье мы разберем ключевые отличия синтаксиса, погрузимся в структуры данных, которые вы будете использовать 90% времени при обработке информации, и научимся писать «pythonic» код.

Философия и базовый синтаксис: Культурный шок

Первое, что бросается в глаза после C++ и PHP — это чистота кода. В Python нет фигурных скобок {} для обозначения блоков кода и точек с запятой ; для завершения инструкций (хотя технически ; допустима, ее использование считается дурным тоном).

Отступы как закон

В C++ и PHP отступы служат для читаемости. В Python отступы — это синтаксис. Блок кода определяется его смещением вправо (обычно 4 пробела).

Сравним условие:

PHP / C++:

Python:

Динамическая типизация и ссылки

Python — язык с сильной динамической типизацией.

  • Динамическая: Тип переменной определяется в момент присваивания (как в PHP).
  • Сильная: Вы не можете просто сложить строку и число (в отличие от PHP, который попытается привести типы, или JS). Python выбросит ошибку TypeError.
  • Важное отличие от C++: переменные в Python — это не коробки с данными, а ссылки (ярлыки) на объекты в памяти.

    !Визуализация ссылочной модели данных в Python: переменные указывают на объекты, а не хранят значения напрямую.

    Пример:

    В C++ аналогом было бы использование указателей или ссылок (std::vector<int>& b = a;). В Python это поведение по умолчанию для всех изменяемых типов.

    Структуры данных для обработки информации

    В Data Science правильный выбор структуры данных определяет эффективность алгоритма. Рассмотрим основные встроенные типы.

    Списки (Lists)

    Это аналог std::vector в C++ или индексированного массива в PHP. Списки изменяемы, упорядочены и могут хранить элементы разных типов (хотя на практике обычно хранят однотипные данные).

    Киллер-фича Python при работе с данными — срезы (slicing).

    Синтаксис среза: list[start:stop:step].

    > Срезы создают копию данных, а не ссылку на оригинальный список (для простых списков).

    Словари (Dictionaries)

    Аналог ассоциативных массивов в PHP (T_{search}O(1)x * xxx$ четный».

    Функции

    Функции объявляются ключевым словом def. Важное отличие от C++: функция может возвращать несколько значений (технически это возвращается кортеж).

    Аргументы

    Python поддерживает именованные аргументы и значения по умолчанию, что делает вызовы функций очень читаемыми.

    Работа с файлами (Context Managers)

    В C++ вы должны помнить о закрытии файла или использовать RAII. В Python для этого есть оператор with`.

    Это гарантирует освобождение ресурсов даже в случае возникновения исключения внутри блока.

    Заключение

    Переход с C++/PHP на Python для работы с данными требует смены парадигмы:

  • Меньше шаблонного кода (boilerplate).
  • Больше работы со встроенными структурами данных (списки, словари).
  • Использование срезов и списковых включений вместо явных циклов с индексами.
  • В следующей статье мы рассмотрим библиотеки NumPy и Pandas, которые превращают Python в мощнейший инструмент аналитики, сравнимый с MATLAB и R.

    Документация Python по структурам данных

    2. Продвинутый Python: ООП, модули, виртуальные окружения и работа с файловой системой

    Продвинутый Python: ООП, модули, виртуальные окружения и работа с файловой системой

    В предыдущей статье мы разобрали базовый синтаксис Python, списки и словари. Теперь пришло время углубиться в архитектурные особенности языка. Как разработчик с опытом в C++ и PHP, вы привыкли к определенным паттернам проектирования. В Python они тоже есть, но часто реализуются иначе.

    В этой статье мы рассмотрим объектно-ориентированное программирование (ООП) в стиле Python, разберемся, как организовать код с помощью модулей, почему виртуальные окружения критически важны для Data Science, и научимся современно работать с файловой системой.

    Объектно-ориентированное программирование: Pythonic Way

    В Python всё является объектом: числа, функции, модули и даже сами классы. Это отличает его от C++, где есть примитивные типы, и от PHP, где функции могут существовать отдельно от объектов.

    Классы и self

    Объявление класса выглядит просто, но есть нюанс, который часто сбивает с толку новичков: явная передача ссылки на экземпляр (self).

    В C++ вы используете this неявно (или явно this->). В Python первый аргумент любого метода экземпляра — это всегда ссылка на сам объект. По конвенции его называют self.

    > В Python нет строгих модификаторов доступа private или protected на уровне языка, как в C++ (private:, public:). Всё основано на соглашениях: имя, начинающееся с _, считается внутренним.

    Магические методы (Dunder methods)

    Сила Python — в так называемых «магических» методах, которые начинаются и заканчиваются двойным подчеркиванием (double underscore). Они позволяют перегружать операторы и определять поведение объектов в стандартных ситуациях.

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

    В методе length мы используем формулу длины вектора (евклидова норма):

    Где — длина (модуль) вектора, — координата по оси абсцисс, а — координата по оси ординат.

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

    Модули и пакеты

    Любой файл с расширением .py — это модуль. Папка с файлом __init__.py (даже пустым) — это пакет.

    Импорт и __name__

    В PHP вы используете include или require. В C++ — #include. В Python система импорта работает как выполнение кода модуля в отдельном пространстве имен.

    Конструкция if __name__ == "__main__": — это стандартная идиома. Она означает: «Выполняй этот блок, только если файл запущен напрямую, а не импортирован как модуль». Это позволяет писать код, который может быть и библиотекой, и исполняемым скриптом одновременно.

    Виртуальные окружения: Dependency Hell

    В мире Data Science это тема №1. У вас будет проект А, требующий pandas версии 1.0, и проект Б, требующий pandas версии 2.0. Если ставить всё в глобальный Python, возникнет конфликт версий.

    !Изоляция зависимостей в виртуальных окружениях

    Виртуальное окружение (venv) — это изолированная директория, содержащая свою копию интерпретатора Python и библиотек.

    Как это работает в консоли:

    После активации команда pip install будет ставить пакеты только в эту папку. Список зависимостей принято фиксировать в файле requirements.txt.

    Работа с файловой системой: Pathlib

    Забудьте про конкатенацию строк для путей, как вы делали это в старом PHP или C (strcat). В Python долгое время использовали модуль os.path, но современный стандарт — это модуль pathlib.

    pathlib реализует объектно-ориентированный подход к путям.

    Почему Pathlib лучше?

    Допустим, нам нужно сформировать путь к файлу данных data/raw/users.csv.

    Старый стиль (os.path):

    Современный стиль (pathlib):

    Это делает код кроссплатформенным (Windows использует \, Linux /), читаемым и безопасным.

    Чтение и запись файлов

    Объекты Path имеют удобные методы для быстрого чтения и записи текста, что избавляет от необходимости писать конструкцию with open(...) для простых операций.

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

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

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

    Заключение

    Мы рассмотрели инструменты, которые превращают скрипты в полноценные инженерные решения:

  • ООП помогает структурировать логику парсеров и обработчиков.
  • Магические методы делают объекты выразительными.
  • Виртуальные окружения спасают от конфликтов библиотек.
  • Pathlib упрощает навигацию по файловой системе.
  • В следующей части курса мы перейдем к «тяжелой артиллерии» Data Science: библиотеке NumPy, которая позволяет работать с многомерными массивами данных с производительностью C++.

    Документация pathlib

    3. Сбор данных: Работа с HTTP-запросами, REST API и парсинг HTML с BeautifulSoup

    Сбор данных: Работа с HTTP-запросами, REST API и парсинг HTML с BeautifulSoup

    В предыдущих модулях мы освоили синтаксис Python, объектно-ориентированное программирование и работу с файловой системой. Теперь мы переходим к одной из самых востребованных областей применения Python — сбору данных (Data Scraping/Mining).

    Как разработчик с опытом в PHP и C++, вы наверняка сталкивались с библиотекой libcurl или функцией file_get_contents. В Python работа с сетью реализована на порядок элегантнее. Мы научимся взаимодействовать с веб-серверами, потреблять API и извлекать данные из HTML-страниц, используя инструменты, ставшие индустриальным стандартом.

    Библиотека Requests: HTTP для людей

    В стандартной библиотеке Python есть модуль urllib, но в реальной разработке он используется редко из-за громоздкого API. Стандартом де-факто является сторонняя библиотека Requests.

    !Визуализация цикла запрос-ответ между клиентом Python и веб-сервером.

    Установка

    Поскольку мы уже настроили виртуальное окружение в прошлой статье, установим библиотеку туда:

    Выполнение запроса

    Сравним выполнение GET-запроса в PHP (cURL) и Python.

    PHP (cURL):

    Python (Requests):

    Код на Python не только короче, но и возвращает объект Response, который содержит всё необходимое: код статуса, заголовки, кодировку и тело ответа.

    Передача параметров

    Вам больше не нужно вручную формировать строку запроса (?key=value&q=test). Библиотека сделает это за вас, корректно экранируя спецсимволы.

    Работа с REST API

    Поскольку вы знаете SQL, вы привыкли работать со структурированными данными. В вебе роль универсального формата данных выполняет JSON. Python имеет встроенную поддержку JSON, а requests делает работу с ним тривиальной.

    Получение данных (GET)

    Отправка данных (POST)

    При отправке данных на сервер (например, авторизация или загрузка формы) мы используем метод post. Аргумент json автоматически добавит заголовок Content-Type: application/json и сериализует словарь.

    Парсинг HTML с BeautifulSoup

    Не всегда данные доступны через удобный API. Часто приходится «парсить» (скрапить) обычные веб-страницы. Здесь на сцену выходит библиотека BeautifulSoup4 (bs4).

    Она строит дерево объектов Python из HTML-кода, позволяя навигировать по нему так же легко, как по DOM в JavaScript.

    Установка:

    Структура страницы и поиск элементов

    Допустим, мы получили HTML-код страницы новостей. Наша задача — собрать заголовки.

    !Иерархическая структура HTML-документа, показывающая вложенность тегов.

    Методы поиска

    В BeautifulSoup есть два основных метода, которые покрывают 90% задач:

  • find(tag, attributes) — возвращает первый найденный элемент.
  • find_all(tag, attributes) — возвращает список всех найденных элементов.
  • > Обратите внимание: аргумент называется class_ (с подчеркиванием), так как class является зарезервированным словом в Python.

    CSS-селекторы

    Так как вы владеете CSS, вам будет удобнее использовать метод .select(). Он принимает стандартные CSS-селекторы, к которым вы привыкли в верстке или jQuery.

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

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

    User-Agent

    Многие серверы блокируют запросы, у которых нет заголовка User-Agent (по умолчанию requests сообщает, что он скрипт). Чтобы притвориться обычным браузером:

    Rate Limiting (Ограничение частоты запросов)

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

    Допустим, сайт разрешает не более запросов в минуту. Тогда минимальная задержка (в секундах) между запросами вычисляется по формуле:

    Где — время задержки в секундах, — количество секунд в минуте, а — допустимое количество запросов в минуту.

    Пример реализации с модулем time:

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

    Объединим всё изученное. Напишем скрипт, который собирает названия и цены книг с вымышленного магазина (структура типична для реальных задач).

    Заключение

    Мы разобрали фундамент сбора данных в Python:

  • Requests позволяет легко выполнять HTTP-запросы, заменяя сложные конструкции cURL.
  • REST API — самый надежный способ получения данных, где Python автоматически конвертирует JSON в словари.
  • BeautifulSoup дает мощные инструменты для навигации по HTML-дереву, используя знакомые вам CSS-селекторы.
  • В следующей статье мы научимся сохранять собранные данные не просто в переменные, а в профессиональные форматы (CSV, Excel) и базы данных, используя библиотеку Pandas.

    Документация Requests Документация BeautifulSoup

    4. Обработка данных: Введение в библиотеку Pandas и интеграция с SQL базами данных

    Обработка данных: Введение в библиотеку Pandas и интеграция с SQL базами данных

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

    Как разработчик, знакомый с SQL, вы привыкли мыслить таблицами, выборками и агрегациями. В экосистеме Python аналогом таблиц базы данных, но работающим в оперативной памяти (in-memory), является библиотека Pandas.

    В этой статье мы разберем архитектуру Pandas, научимся манипулировать данными быстрее, чем на чистом C++, и интегрируем наши скрипты с SQL-базами данных.

    Что такое Pandas и зачем он нужен?

    Pandas — это высокоуровневая библиотека, построенная поверх NumPy (библиотеки для матричных вычислений на C). Это означает, что операции в Pandas векторизованы и выполняются на низком уровне, минуя медленный интерпретатор Python в циклах.

    Если в PHP вы работаете с массивами массивов (\bar{x}\bar{x}nx_ii$-го элемента.

    В Pandas это делается одной командой:

    Группировка (Group By)

    Pandas реализует парадигму «Split-Apply-Combine», аналогичную SQL GROUP BY.

    Добавим категорию книгам:

    Интеграция с SQL базами данных

    Поскольку вы уже знаете SQL, Pandas станет идеальным компаньоном. Вы можете выгружать результаты сложных запросов в DataFrame, обрабатывать их средствами Python (например, использовать библиотеки машинного обучения) и загружать обратно.

    Для соединения используется библиотека SQLAlchemy.

    Чтение из SQL

    Запись в SQL

    После обработки данных (очистка, добавление вычисляемых столбцов) мы можем сохранить их в новую таблицу.

    Это избавляет от необходимости писать сотни строк кода с INSERT INTO ... VALUES (...).

    Обработка отсутствующих данных

    В реальном мире данные «грязные». В SQL это NULL, в Python — None, а в Pandas/NumPy — NaN (Not a Number).

    Заключение

    Pandas — это «швейцарский нож» для данных в Python. Он заменяет собой Excel и значительную часть SQL-запросов, позволяя проводить глубокий анализ и трансформацию данных в несколько строк кода.

    Мы рассмотрели:

  • Структуры Series и DataFrame.
  • Фильтрацию и векторизованные операции.
  • Бесшовную интеграцию с SQL через read_sql и to_sql`.
  • В следующем модуле мы перейдем к визуализации полученных данных, чтобы превратить сухие цифры в понятные графики и дашборды.

    Документация Pandas Документация SQLAlchemy

    5. Автоматизация и ETL: Обработка ошибок, логирование и построение конвейеров данных

    Автоматизация и ETL: Обработка ошибок, логирование и построение конвейеров данных

    В предыдущих модулях мы прошли путь от базового синтаксиса Python до сбора данных с помощью requests и их анализа в pandas. Вы уже умеете писать скрипты, которые делают полезную работу. Но есть проблема: скрипт, запущенный на локальной машине один раз — это еще не инженерное решение.

    В реальном мире сети падают, API меняют форматы ответов, диски переполняются, а базы данных уходят на обслуживание. Если ваш скрипт просто падает с ошибкой в консоль в 3 часа ночи, это плохой скрипт.

    В этой статье мы превратим разрозненный код в надежный ETL-конвейер (Pipeline). Мы разберем профессиональную обработку ошибок, настроим логирование вместо print() и научимся автоматизировать запуск задач.

    Что такое ETL?

    ETL — это аббревиатура, описывающая классический процесс интеграции данных:

  • Extract (Извлечение): Получение данных из источника (API, парсинг сайта, чтение логов, SQL-запрос).
  • Transform (Преобразование): Очистка, фильтрация, агрегация, приведение типов (то, что мы делали в Pandas).
  • Load (Загрузка): Сохранение результата в целевую систему (CSV, Data Warehouse, новая таблица SQL).
  • !Схематичное изображение потока данных от источника к хранилищу через обработку.

    Ваша задача как разработчика — обеспечить, чтобы этот поток не прерывался, а если прерывался — вы знали почему.

    Обработка исключений: Pythonic Way

    Вы знакомы с try-catch в PHP и C++. В Python используется конструкция try-except. Однако в Python принято следовать принципу EAFP: It's Easier to Ask for Forgiveness than Permission (Проще попросить прощения, чем разрешения).

    Вместо того чтобы проверять, существует ли файл или доступен ли ключ в словаре (как часто делают в C++), в Python мы просто пытаемся выполнить операцию и ловим ошибку.

    Полный синтаксис

    В Python блок обработки ошибок богаче, чем во многих других языках. У него есть ветки else и finally.

    Важное правило: Никогда не пишите просто except:. Это перехватит абсолютно всё, включая KeyboardInterrupt (Ctrl+C), и вы не сможете остановить свой скрипт. Всегда указывайте тип исключения или хотя бы except Exception:.

    Логирование: Забудьте про print()

    Использование print() для отладки продакшн-кода — это дурной тон.

  • Вы не можете легко отключить print.
  • Вы не знаете, когда и где произошло событие.
  • Вы не можете разделить сообщения по важности.
  • В Python есть мощный встроенный модуль logging.

    Уровни логирования

  • DEBUG: Детальная информация для отладки (значения переменных, шаги цикла).
  • INFO: Подтверждение того, что всё идет по плану («Скрипт запущен», «Подключились к БД»).
  • WARNING: Неожиданное событие, но скрипт работает (например, «Медленный ответ API»).
  • ERROR: Серьезная проблема, часть функции не выполнилась («Не удалось сохранить файл»).
  • CRITICAL: Фатальная ошибка, программа не может продолжать работу.
  • Настройка логгера

    Теперь в файле etl_process.log будет: 2023-10-25 14:30:01,123 - INFO - Запуск ETL процесса 2023-10-25 14:30:01,125 - ERROR - Произошла ошибка вычисления...

    Паттерн Retry (Повторные попытки)

    Сеть ненадежна. Если API вернул 503 (Service Unavailable), это не значит, что скрипт сломан. Это значит, что нужно подождать и попробовать снова.

    Для этого используется алгоритм Exponential Backoff (Экспоненциальная задержка). Мы увеличиваем время ожидания после каждой неудачи, чтобы не "задудосить" сервер.

    Формула расчета времени ожидания:

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

    Реализуем это с помощью декоратора (еще одна мощная фича Python):

    Конфигурация и безопасность

    Никогда не храните пароли от базы данных или API-ключи прямо в коде (.py файлах). Если вы случайно закоммитите их в Git, они станут достоянием общественности.

    Стандарт индустрии — использование переменных окружения и .env файлов.

  • Создайте файл .env в корне проекта:
  • Добавьте .env в .gitignore.
  • Используйте библиотеку python-dotenv для чтения:
  • Автоматизация запуска

    Написанный ETL-скрипт нужно запускать регулярно. Есть два основных пути.

    1. Системные планировщики (Cron / Task Scheduler)

    Это классический путь администрирования.

    Linux (Cron): 0 9 * /path/to/venv/bin/python /path/to/project/main.py (Запуск каждый день в 9:00 утра).

    2. Python-планировщики (Библиотека schedule)

    Если вы хотите, чтобы расписание было частью кода (Infrastructure as Code) и скрипт работал как сервис (демон), используйте библиотеку schedule.

    Этот подход удобен тем, что он кроссплатформенный и не требует настройки ОС.

    Практический пример: Класс ETL-конвейера

    Соберем всё вместе в структуру, которую не стыдно показать на код-ревью.

    Заключение

    Мы перешли от написания скриптов «на коленке» к созданию надежных приложений.

  • Логирование позволяет вам видеть, что происходит внутри "черного ящика".
  • Обработка исключений делает код устойчивым к внешним факторам.
  • Переменные окружения защищают ваши секреты.
  • Структура классов позволяет легко расширять логику (например, добавить новый источник данных).
  • В следующей, заключительной статье курса, мы коснемся темы визуализации данных с помощью библиотек Matplotlib и Seaborn, чтобы превратить наши таблицы в понятные графики.

    Документация модуля logging Документация библиотеки schedule