Интенсив Python за 1 месяц: основы, анализ данных и сбор структуры сайта

Курс помогает освоить ключевые основы Python за 4 недели и перейти к практическим задачам: обработке данных и извлечению/анализу структурированной информации с сайтов. Итог — умение писать чистый код, работать с данными и создавать прототип пайплайна для сбора и анализа данных со страниц.

1. База Python: синтаксис, типы данных, условия и циклы

База Python: синтаксис, типы данных, условия и циклы

Python в этом курсе — основной инструмент для двух больших задач:

  • Писать понятный код и автоматизировать рутину
  • Подготовиться к анализу данных и к сбору структуры сайта (краулинг, парсинг, обработка результатов)
  • Эта статья закладывает фундамент: синтаксис, базовые типы данных, ветвления и циклы.

    Как читать и запускать Python-код

    Python-код выполняется сверху вниз, строка за строкой. Важнейшее правило — отступы задают структуру блоков (условий, циклов, функций).

    Минимальный пример

    Комментарии

  • Однострочный комментарий начинается с #
  • Отступы

    Отступы в Python обычно делают 4 пробелами. Не смешивайте табы и пробелы.

    !Схема показывает, как условие делит выполнение на ветки и почему отступы важны

    Переменные и присваивание

    Переменная — это имя, которое указывает на значение.

    Правила именования (практичные и общепринятые):

  • Используйте snake_case: total_sum, page_count
  • Не начинайте имя с цифры
  • Не используйте зарезервированные слова (if, for, class и другие)
  • Базовые типы данных

    Тип данных определяет, что хранится и какие операции допустимы.

    Числа: int и float

  • int — целые числа: 1, -50, 0
  • float — числа с точкой: 3.14, -0.5
  • Строки: str

    Строка — это текст.

    Полезные операции:

    Часто используемые методы строк:

    Логический тип: bool

    bool бывает только двух значений: True и False.

    Пустое значение: None

    None означает значение отсутствует.

    Это часто встречается при обработке данных: например, если у поля на странице нет значения.

    Коллекции (структуры данных)

    Список: list

    Список — изменяемая упорядоченная коллекция.

    Доступ по индексу:

    Кортеж: tuple

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

    Словарь: dict

    Словарь хранит пары ключ → значение. Это ключевая структура для работы с данными сайтов: страницу удобно представлять как словарь полей.

    Безопасное получение значения:

    Множество: set

    Множество хранит уникальные элементы.

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

    Ввод и вывод

    Вывод в консоль

    Ввод пользователя

    input() всегда возвращает строку.

    Если строка не похожа на число, int(s) вызовет ошибку. Позже вы научитесь обрабатывать это через try/except.

    Операторы сравнения и логика

    Операторы сравнения возвращают bool:

  • == равно
  • != не равно
  • > больше
  • < меньше
  • >= больше или равно
  • <= меньше или равно
  • Логические операторы:

  • and — и
  • or — или
  • not — не
  • Условия: if, elif, else

    Условия позволяют выполнять разные ветки кода.

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

    Циклы

    Циклы нужны, чтобы повторять действия: пройти по списку ссылок, обработать строки файла, посчитать метрики.

    Цикл for

    Итерация по списку:

    range() — генерация последовательности чисел:

    Если нужны и индекс, и значение — используйте enumerate():

    Цикл while

    while работает, пока условие истинно.

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

    break и continue

  • break — прервать цикл
  • continue — перейти к следующей итерации
  • Типовые ошибки новичка и как их избежать

  • IndentationError из-за неправильных отступов
  • TypeError при попытке сложить числа и строки
  • KeyError при обращении к несуществующему ключу словаря
  • Как это связано с будущими темами курса

    В следующих материалах вы будете применять эту базу напрямую:

  • Анализ данных: списки, словари, циклы и условия используются для очистки и преобразования данных
  • Сбор структуры сайта: список ссылок, словарь полей страницы, проверка условий (страница найдена, статус-код, есть ли нужные элементы)
  • Полезные официальные источники

  • Python 3 Documentation
  • The Python Tutorial
  • More Control Flow Tools
  • Built-in Types
  • 2. Функции, модули, ошибки, работа с файлами и JSON

    Функции, модули, ошибки, работа с файлами и JSON

    Эта статья продолжает базу из предыдущего материала (типы данных, условия и циклы) и добавляет то, без чего не получится писать реальные программы:

  • Функции: чтобы не копировать код и собирать решение из понятных блоков
  • Модули: чтобы подключать готовые возможности Python и структурировать проект
  • Ошибки и исключения: чтобы код не падал на «грязных» данных
  • Файлы: чтобы читать/писать результаты анализа и выгрузки
  • JSON: основной формат обмена данными для сайтов и API
  • Для анализа данных и сбора структуры сайта все эти темы используются ежедневно: вы читаете входные данные, обрабатываете, ловите ошибки, сохраняете результат в файл (часто JSON).

    Функции

    Функция — это именованный блок кода, который:

  • принимает входные данные (аргументы)
  • выполняет действия
  • возвращает результат (return)
  • Зачем нужны функции

  • Повторное использование: один раз написали — используете много раз
  • Читаемость: код превращается в «шаги»
  • Тестируемость: легче проверять маленькие куски логики
  • Простейший пример

    Что здесь важно:

  • def начинает определение функции
  • параметры в скобках — входные данные
  • return возвращает значение вызывающему коду
  • return и None

    Если return не указан, функция вернет None.

    Это нормально: не все функции должны «что-то возвращать». Иногда их задача — выполнить действие.

    Аргументы: позиционные, именованные, значения по умолчанию

  • path="/" — значение по умолчанию
  • можно передавать аргументы по имени: base_url=...
  • Несколько возвращаемых значений (кортеж)

    Python позволяет вернуть несколько значений, фактически возвращается кортеж.

    Область видимости (scope)

    Переменные, созданные внутри функции, не видны снаружи.

    Это помогает избегать «случайных» конфликтов имен.

    Докстринги

    Докстринг — строка в начале функции, которая описывает ее назначение.

    Докстринги полезны в учебе и в командной разработке.

    Модули и импорт

    Модуль — это файл .py с кодом. Python позволяет подключать модули и использовать функции/классы из них.

    Импорт стандартных модулей

    Разные способы импорта

    Практическое правило:

  • import json обычно читается проще
  • from ... import ... удобен, но может усложнить понимание, откуда взялась функция
  • Как Python ищет модули

    В первую очередь:

  • в текущей папке проекта
  • в стандартной библиотеке Python
  • в установленных пакетах (в среде/интерпретаторе)
  • Если модуль не найден, будет ModuleNotFoundError.

    Структура проекта (минимально)

    Если вы разбиваете код на файлы, часто получается так:

  • main.py — точка входа
  • utils.py — полезные функции
  • io.py — чтение/запись файлов (или похожее имя)
  • Важно: названия файлов не должны конфликтовать с модулями стандартной библиотеки. Например, не называйте свой файл json.py.

    Ошибки и исключения

    Когда Python не может продолжить выполнение, он выбрасывает исключение (ошибку) — например:

  • ValueError — неверное значение (например, int("abc"))
  • TypeError — неправильный тип (например, попытка сложить строку и число)
  • KeyError — нет ключа в словаре при обращении data["x"]
  • FileNotFoundError — файл не найден
  • Обработка исключений: try/except

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

    Несколько типов исключений

    else и finally

  • else выполняется, если ошибок не было
  • finally выполняется всегда (удобно для освобождения ресурсов)
  • Когда не стоит «глушить» ошибки

    Плохо:

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

  • вывести сообщение
  • записать в лог (позже)
  • пробросить ошибку дальше
  • Работа с файлами

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

    Открытие файла: with open(...)

    Главное правило: используйте with. Он гарантирует, что файл будет закрыт.

  • режим "w" — запись (перезапишет файл)
  • encoding="utf-8" — почти всегда правильный выбор для русского текста
  • Чтение файла целиком

    Чтение построчно

    Построчное чтение удобно, если файл большой.

    Частые проблемы

  • FileNotFoundError: неверный путь или файл не создан
  • «кракозябры» в тексте: забыли encoding="utf-8"
  • забыли \n при записи строк
  • JSON

    JSON (JavaScript Object Notation) — текстовый формат данных. На сайтах и в API он встречается постоянно.

    Соответствие типов JSON и Python:

    | JSON | Python | |---|---| | object | dict | | array | list | | string | str | | number | int / float | | true/false | True/False | | null | None |

    Преобразование строки JSON в Python-объект

  • json.loads() принимает строку JSON и возвращает Python-объект
  • Преобразование Python-объекта в строку JSON

    Параметры:

  • ensure_ascii=False — чтобы русские буквы не превращались в \u041f...
  • indent=2 — красивое форматирование
  • Чтение и запись JSON-файлов

  • json.dump() / json.load() работают с файлом
  • json.dumps() / json.loads() работают со строкой
  • Типовой пайплайн для задач курса

    !Схема показывает, как чтение JSON, функции обработки и обработка ошибок соединяются в единый процесс

    Мини-проектный пример: обработка списка страниц

    Ниже пример, который связывает все темы: функции, ошибки, файлы, JSON.

    Задача: прочитать список страниц из JSON, оставить только успешные (status == 200), нормализовать URL и сохранить результат.

    Что здесь закрепляется:

  • функции разделяют логику на понятные части
  • try/except защищает от проблем с файлом и JSON
  • with open(...) безопасно работает с файлами
  • json.load и json.dump соединяют код с данными
  • Куда дальше

    Эти навыки — база для следующих шагов курса:

  • в анализе данных вы будете читать файлы, чистить значения функциями и сохранять результат
  • в сборе структуры сайта вы будете собирать данные по страницам в dict, накапливать их в list и сохранять в JSON
  • Официальные источники

  • Определение функций (The Python Tutorial)
  • Модули (The Python Tutorial)
  • Ошибки и исключения (The Python Tutorial)
  • Чтение и запись файлов (The Python Tutorial)
  • Модуль json (Python Standard Library)
  • PEP 8 — стиль кода
  • 3. Структуры данных и алгоритмическое мышление для практики

    Структуры данных и алгоритмическое мышление для практики

    Эта статья связывает две предыдущие темы курса:

  • из базы Python вы уже умеете работать с типами данных, условиями и циклами
  • из темы про функции, ошибки, файлы и JSON вы умеете оформлять логику в функции, безопасно обрабатывать сбои и сохранять результаты
  • Теперь добавляем то, что отличает «код, который работает» от «кода, который решает задачу надежно и масштабируемо»: правильный выбор структур данных и алгоритмическое мышление.

    В анализе данных и в сборе структуры сайта вы постоянно делаете одно и то же:

  • собираете элементы (страницы, ссылки, записи)
  • чистите и нормализуете значения
  • убираете дубликаты
  • группируете и считаете
  • сортируете и сохраняете результат
  • Алгоритмическое мышление

    Алгоритмическое мышление в Python-практике — это привычка решать задачу в понятных шагах.

    Удобная схема:

  • Сформулировать вход и выход
  • Выписать ограничения и «грязные» случаи (пустые строки, None, дубликаты)
  • Подобрать структуры данных (список, множество, словарь)
  • Разбить решение на функции
  • Пройти тестовыми примерами и проверить крайние случаи
  • Пример формулировки для краулинга:

  • вход: список URL
  • выход: список словарей страниц, где у каждой страницы есть url, status, title, links
  • ограничения: ссылки могут повторяться, некоторые страницы недоступны, у некоторых нет title
  • Выбор структуры данных: что взять и почему

    Главное правило: сначала выберите структуру данных, потом пишите цикл.

    | Структура | Что хранит | Сильная сторона | Типовой кейс в курсе | |---|---|---|---| | list | упорядоченные элементы | удобно накапливать и проходить по порядку | список страниц, список ссылок на странице | | dict | ключ → значение | быстрый доступ по ключу и гибкая структура записи | страница как набор полей: {"url": ..., "title": ...} | | set | уникальные элементы | убирает дубликаты автоматически | уникальные URL, уникальные теги | | tuple | упорядоченные элементы (обычно неизменяемые) | удобно возвращать несколько значений | вернуть (title, h1) из функции |

    Практический ориентир:

  • если нужно сохранить все элементы и порядок важен — берите list
  • если нужно хранить уникальные значения — берите set
  • если нужно хранить запись с полями или делать индекс по ключу — берите dict
  • Типовые алгоритмические паттерны в обработке данных

    Фильтрация

    Фильтрация — это «оставить только подходящие элементы».

    Пример: оставить только успешные страницы.

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

  • вы не меняете исходный список в процессе обхода
  • вы явно контролируете критерий отбора
  • Преобразование (нормализация)

    Преобразование — это «привести данные к удобному виду».

    Дальше такую функцию удобно применять в цикле:

    Подсчет (частоты, метрики)

    Подсчет — один из самых частых паттернов в анализе данных.

    Пример: сколько раз встречается каждый статус.

    Если ключа нет, мы создаем его со стартовым значением. Это и есть алгоритмическое мышление: вы заранее предусмотрели отсутствие ключа.

    Группировка

    Группировка — это «разложить элементы по корзинам».

    Пример: сгруппировать страницы по статусу.

    Результат — dict, где ключ это статус, а значение — list страниц.

    Быстрые проверки: in для list, set, dict

    Проверка «уже видели или нет» — ключевая для краулинга.

    Идея:

  • visited как set хранит уже посещенные URL
  • при нахождении новой ссылки мы быстро проверяем if url in visited:
  • Для структуры сайта это критично: без set вы легко получите повторы и риск зациклиться.

    Сортировка: делаем данные удобными для просмотра

    В Python обычно используют:

  • sorted(iterable, key=...) возвращает новый список
  • list.sort(key=...) сортирует список на месте
  • Пример: отсортировать страницы по URL.

    Здесь key возвращает кортеж из двух элементов:

  • сначала признак p.get("url") is None, чтобы None ушли в конец
  • затем сам URL для сортировки
  • Такой прием часто нужен на «грязных» данных, где поле может отсутствовать.

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

    Стек и очередь: базовая модель краулинга

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

  • стек: принцип последний пришел — первый вышел, обычно через list.append() и list.pop()
  • очередь: принцип первый пришел — первый вышел, удобно через collections.deque
  • deque хорош тем, что быстро вытаскивает элемент слева методом popleft().

    !Схема показывает, как очередь и множество предотвращают повторы при сборе структуры сайта

    Мини-скелет обхода (без реальных запросов, только логика структур данных):

    Алгоритмические идеи, которые здесь закрепляются:

  • очередь хранит «что обработать дальше»
  • множество хранит «что уже обработано»
  • список хранит «результаты»
  • continue помогает аккуратно пропускать плохие элементы
  • Практический пайплайн: от сырого списка ссылок к JSON со структурой

    Ниже пример, который соединяет весь фундамент курса:

  • функции для нормализации
  • алгоритмы фильтрации и удаления дублей
  • структуры данных list, set, dict
  • запись результата в JSON
  • обработка ошибок чтения файла
  • Что вы получите на выходе:

  • воспроизводимый пайплайн обработки
  • структурированный JSON, который дальше легко анализировать
  • основу для следующего шага курса, где появятся реальные запросы к сайту и извлечение ссылок/полей
  • Частые ошибки в алгоритмах новичка

  • менять список, по которому вы идете в for (часть элементов пропускается)
  • забывать про дубликаты ссылок (краулер раздувается и зацикливается)
  • не предусматривать None и пустые строки при нормализации
  • складывать в один огромный цикл все действия вместо разделения на функции
  • Если сомневаетесь, вернитесь к базовому подходу:

  • выделите функции нормализации
  • отдельно сделайте фильтрацию
  • отдельно сделайте группировку или подсчет
  • только потом сохраняйте в файл
  • Полезные источники

  • Встроенные типы данных (Python Documentation)
  • Типы контейнеров (Python Documentation)
  • deque (Python Documentation)
  • Sorting HOWTO (Python Documentation)
  • Сложность операций у коллекций (Python Wiki)
  • 4. ООП и чистый код: классы, проектирование, тестирование

    ООП и чистый код: классы, проектирование, тестирование

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

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

  • ООП (объектно-ориентированное программирование): классы, объекты, композиция
  • чистый код: понятная структура, ответственность, именование, минимальные побочные эффекты
  • тестирование: автоматическая проверка ключевой логики
  • Зачем ООП в задачах анализа данных и сбора структуры сайта

    В задачах курса вы постоянно работаете с сущностями, которые удобно представить как объекты:

  • страница (URL, статус, заголовки, ссылки)
  • краулер (очередь, visited, ограничения)
  • хранилище результата (файл JSON, папка, формат)
  • парсер (как извлекать ссылки/поля из HTML)
  • Функции остаются важнейшим инструментом, но классы помогают упаковать состояние и поведение вместе. Например, у краулера есть состояние (очередь, посещенные URL) и поведение (взять следующий URL, скачать, распарсить, сохранить).

    Класс и объект: базовые понятия

  • Класс — шаблон (описание), как устроен объект.
  • Объект — конкретный экземпляр класса с собственными данными.
  • Атрибуты — данные объекта.
  • Методы — функции, которые принадлежат классу и работают с данными объекта.
  • Минимальный пример класса

    Что важно понять:

  • __init__ вызывается при создании объекта и инициализирует атрибуты.
  • self — ссылка на текущий объект.
  • c.value — состояние объекта.
  • Модель данных: класс страницы

    Для анализа структуры сайта удобно хранить данные страницы в одном объекте.

    Вариант на обычном классе

    Обратите внимание на прием links or []: он защищает от ситуации, когда в links пришло None.

    Вариант через dataclasses

    dataclasses — стандартный модуль Python, который помогает описывать “контейнеры данных” короче.

    Почему field(default_factory=list) важен:

  • он создает новый пустой список для каждого объекта
  • это предотвращает классическую ошибку, когда один и тот же список случайно разделяют все экземпляры
  • Инкапсуляция и “инварианты”

    Инкапсуляция — идея, что объект сам отвечает за корректность своего состояния. На практике это означает: не только хранить данные, но и проверять их.

    Например, вы хотите гарантировать, что status всегда целое число.

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

    Часто удобно делать отдельную функцию нормализации (из предыдущих статей), а класс использовать как структуру результата.

    Наследование и композиция

    Наследование

    Наследование — это “класс A расширяет класс B”. Например, можно сделать разные типы страниц.

    Наследование полезно, когда:

  • у объектов реально общий “скелет”
  • вы точно понимаете, что подкласс всегда может использоваться там, где ждут базовый класс
  • Композиция

    Композиция — это “объект состоит из других объектов”. Для задач курса композиция обычно безопаснее наследования.

    Например, краулер использует загрузчик и парсер, а не “является” их разновидностью.

    !Схема показывает, как разделить проект на компоненты, чтобы код было проще расширять и тестировать

    Проектирование: разделяем ответственность

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

    Для мини-проекта “сбор структуры сайта” типичная декомпозиция выглядит так:

  • Fetcher: получить содержимое страницы (в будущем — HTTP-запрос)
  • Parser: извлечь данные из содержимого (title, ссылки)
  • Crawler: управлять обходом (очередь, visited, лимиты)
  • Storage: сохранить результат (JSON)
  • Analyzer: посчитать метрики по готовому списку страниц
  • Так вы избегаете “комбайна”, где один класс делает всё.

    Скелет классов (без реального HTTP и HTML)

    Обратите внимание: Crawler не знает, как именно скачивать и парсить — он только управляет процессом. Это резко повышает тестируемость.

    Чистый код: практические правила для вашего уровня

    Именование

  • имена функций и переменных должны отвечать на вопрос “что это” или “что делает”
  • избегайте a, x, tmp, если это не счетчик цикла
  • Пример:

    Маленькие функции и методы

    Если функция не помещается в голове за один раз, её стоит разделить.

    Практический ориентир:

  • функция делает один шаг пайплайна (нормализовать, отфильтровать, сгруппировать, сохранить)
  • метод класса делает одно действие (fetch, parse, crawl)
  • Минимум побочных эффектов

    Побочный эффект — когда функция “не только возвращает результат”, но и меняет внешний мир (файл, сеть, глобальные переменные, данные, переданные по ссылке).

    Для тестирования полезно разделять:

  • чистую логику (нормализация, подсчет, группировка)
  • операции ввода/вывода (файлы, сеть)
  • Не усложняйте ООП

    Частая ошибка — делать классы ради классов. ООП оправдано, когда есть:

  • состояние, которое нужно хранить между вызовами
  • “роли” компонентов (Fetcher/Parser/Storage)
  • необходимость подменять реализацию (например, подставить тестовый Fetcher)
  • Тестирование: что и как проверять

    Зачем тесты в этом курсе

    Тесты особенно полезны, когда вы:

  • чистите данные (много “грязных” случаев)
  • строите обход ссылок (важно не зациклиться)
  • сохраняете структуру данных в ожидаемом формате
  • Что тестировать в первую очередь

    | Часть проекта | Почему важно | Пример теста | |---|---|---| | Нормализация | много краевых случаев | None, пустые строки, пробелы | | Извлечение ссылок | легко ошибиться в правилах | относительные/абсолютные ссылки | | Удаление дублей | критично для краулинга | set, порядок | | Подсчеты/группировки | основа анализа | частоты статусов |

    Минимальный пример на unittest

    unittest — стандартный модуль Python. Его достаточно для задач курса.

    Что здесь закрепляется:

  • тесты проверяют именно логику, без файлов и сети
  • каждый тест — один понятный случай
  • при ошибке вы сразу видите, какой сценарий сломался
  • Тестирование классов через подмену зависимостей

    Ключевой прием проектирования под тесты — внедрение зависимостей: Crawler получает fetcher и parser снаружи. Тогда в тесте вы можете подставить “фейковую” реализацию.

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

    Как это связано со следующими шагами курса

    После этой темы вам будет проще перейти к “настоящему” проекту:

  • добавить реальный Fetcher (HTTP-запросы)
  • добавить реальный Parser (извлечение ссылок и полей)
  • сохранять результат через Storage в JSON
  • анализировать итоговый JSON (статусы, глубина, частоты, ошибки)
  • При этом структура проекта останется понятной, а ключевая логика будет защищена тестами.

    Полезные официальные источники

  • Документация Python: классы
  • Документация Python: dataclasses
  • Документация Python: unittest
  • Документация Python: typing
  • PEP 8 — стиль кода
  • 5. Анализ данных: NumPy, pandas, очистка и агрегации

    Анализ данных: NumPy, pandas, очистка и агрегации

    В предыдущих статьях вы научились писать функции, работать с файлами и JSON, выбирать структуры данных и строить простой краулер. Теперь добавим инструменты, которые превращают «список словарей» в удобный объект для анализа: NumPy и pandas.

    В рамках курса это нужно для двух практических сценариев:

  • анализировать результаты сбора структуры сайта (например, pages.json: статусы, дубликаты, глубины URL, распределения)
  • готовить и очищать данные так, чтобы их можно было агрегировать, сравнивать и сохранять в отчеты
  • !Общая картина: как данные из JSON превращаются в таблицу, очищаются и агрегируются

    Что такое NumPy и pandas

  • NumPy — библиотека для быстрых вычислений над массивами чисел (векторные операции, маски, преобразования типов).
  • pandas — библиотека для табличных данных: колонки, строки, фильтрация, объединения, группировки, сводные таблицы.
  • Практическая модель:

  • NumPy чаще «под капотом», когда вы делаете вычисления по числовым колонкам.
  • pandas — основной инструмент, когда данные уже похожи на таблицу.
  • Официальные источники:

  • Документация NumPy
  • Документация pandas
  • Установка и импорт

    Установка (в терминале):

    Импорт в коде:

    Если вы уже делали проекты из прошлых статей, удобно держать зависимости в отдельном окружении (виртуальная среда). Это не обязательно для понимания темы, но полезно на практике.

    NumPy: массивы и векторные операции

    Массив ndarray

    NumPy хранит данные в объекте ndarray (массив). Он отличается от list тем, что рассчитан на массовые операции.

    Векторизация: «операция сразу над всей колонкой»

    Ключевая идея: вместо цикла по элементам вы пишете одно выражение.

    Проверка a > 2 возвращает булев массив (маску). Маски применяют для фильтрации:

    Где это полезно в анализе структуры сайта

  • преобразовать длину URL в число и посчитать распределения
  • отфильтровать строки по числовым условиям (например, status >= 400)
  • быстро посчитать метрики по колонкам
  • На практике в pandas вы будете делать это почти так же, только вместо массивов — колонки DataFrame.

    pandas: Series и DataFrame

    Series

    Series — это «одна колонка» с индексом.

    DataFrame

    DataFrame — таблица: колонки + строки.

    Основная логика анализа в pandas почти всегда выглядит так:

  • загрузили DataFrame
  • посмотрели форму и типы
  • очистили данные
  • сделали агрегаты
  • сохранили результаты
  • Загрузка данных: CSV и JSON

    CSV

    Сохранение:

    JSON

    Для структуры сайта вы часто будете работать с JSON вида «список словарей»:

    Чтение такого файла:

    Сохранение:

    Полезные ссылки:

  • pandas.read_json
  • DataFrame.to_csv
  • Быстрый осмотр данных

    После загрузки важно сразу понять: сколько строк, какие колонки, где пропуски.

    info() показывает типы и пропуски:

    Если есть числовые колонки, describe() дает базовую статистику:

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

    Очистка — это приведение данных к предсказуемому виду. В прошлых статьях вы делали это функциями и условиями; в pandas те же идеи применяются к колонкам.

    Пропуски: NaN и None

    В pandas пропуск часто хранится как NaN (для чисел) или как специальное «пустое значение» в колонке.

    Проверки:

    Заполнение:

    Приведение типов

    Очень частая проблема: числа прочитались как строки. Тогда сравнения и агрегации дают неожиданные результаты.

    Дата и время (если вы сохраняли время загрузки страниц):

    Ссылки:

  • pandas.to_numeric
  • pandas.to_datetime
  • Дубликаты

    Например, если краулер повторно добавлял один и тот же URL.

    Нормализация строк

    Это продолжение темы про функции нормализации. В pandas часто используют строковые методы через .str.

    Если нужно применить вашу функцию нормализации из прошлых статей, используйте map:

    Правило выбора:

  • если задача решается встроенными методами .str..., используйте их
  • если логика сложная, переносите ее в функцию и применяйте через map
  • Колонки из «сложных» значений

    В данных структуры сайта поле links часто является списком. Это нормально, но агрегировать такие колонки нужно аккуратно.

    Базовый прием: посчитать количество ссылок.

    Агрегации: подсчеты, группировки, сводные

    Агрегация — это «сжать много строк в краткий итог». Для анализа краулинга это центральная часть.

    Частоты: value_counts

    Это быстрый ответ на вопрос: «каких статусов больше всего?».

    Фильтрация перед агрегацией

    Группировка: groupby

    Если нужно считать несколько метрик по группам, используйте groupby.

    Что здесь происходит:

  • groupby("status") делит строки на группы по значению status
  • agg(...) считает агрегаты по каждой группе
  • reset_index() превращает результат обратно в «обычную таблицу»
  • Ссылка:

  • pandas.DataFrame.groupby
  • Производные признаки: пример «глубина URL»

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

    Сводные таблицы: pivot_table

    Если вы хотите таблицу вида «строки = глубина, колонки = статус, значения = количество», удобен pivot_table.

    Ссылка:

  • pandas.pivot_table
  • Объединение таблиц: concat и merge

    В анализе данных часто нужно соединять источники.

  • concat — «склеить таблицы» по строкам или колонкам.
  • merge — «соединить по ключу», как в базах данных.
  • concat

    merge

    Допустим, у вас есть таблица с описанием типов страниц или групп URL.

    Ссылка:

  • pandas.DataFrame.merge
  • Мини-проект: анализ pages.json после краулинга

    Ниже пример, который связывает прошлые темы курса (файлы, JSON, функции нормализации, структуры данных) с pandas-анализом.

    Цель:

  • загрузить pages.json (результат обхода)
  • привести данные к аккуратному виду
  • посчитать сводку по статусам и глубине
  • сохранить итоговые таблицы
  • Что важно в этом примере:

  • вы используете функции нормализации из базового Python, но применяете их к колонке
  • вы отделяете очистку (типов, дублей, пропусков) от агрегаций
  • результаты сохраняются в CSV, чтобы их было удобно смотреть и сравнивать между запусками
  • Типовые ошибки при работе с pandas (и как их избегать)

  • Пытаться анализировать данные без df.info() и проверки типов.
  • Не учитывать пропуски и пустые строки в ключевых полях (url, status).
  • Путать apply с векторными операциями.
  • Делать агрегации по «грязным» данным, а потом удивляться результатам.
  • Практическая привычка:

  • сначала привести типы и значения к нормальному виду
  • потом считать агрегаты
  • потом сохранять результаты
  • Куда дальше в курсе

    Следующий логичный шаг после этой статьи:

  • подключить реальный сбор структуры сайта (HTTP-запросы и парсинг HTML)
  • сохранять результат в JSON
  • строить отчеты в pandas: ошибки, глубина, самые «связанные» страницы, дубликаты, проблемы нормализации
  • Так вы замыкаете цикл: сбор данныхочисткаагрегациивывод результатов.

    6. Сбор данных с сайтов: HTTP, HTML, парсинг, пагинация

    Сбор данных с сайтов: HTTP, HTML, парсинг, пагинация

    Эта тема соединяет все, что вы уже прошли в курсе:

  • из базового Python вы берете условия, циклы и структуры данных
  • из темы про функции, ошибки, файлы и JSON — надежную обработку «грязных» случаев и сохранение результата
  • из ООП и проектирования — разбиение проекта на компоненты FetcherParserCrawlerStorage
  • из анализа данных (pandas) — превращение выгрузки в таблицу и расчет метрик
  • Цель статьи: научиться получать HTML по HTTP, извлекать данные из HTML и обходить страницы каталога через пагинацию, чтобы в итоге собрать структуру сайта и подготовить данные для анализа.

    !Общая картина процесса: запрос → HTML → парсинг → нормализация → сохранение → анализ

    HTTP простыми словами: что происходит при скачивании страницы

    Когда вы открываете страницу в браузере, браузер делает HTTP-запрос к серверу и получает HTTP-ответ.

    Ключевые элементы:

  • URL: адрес ресурса, например https://example.com/catalog?page=2
  • Метод: чаще всего GET для получения страницы
  • Статус-код: число, которое говорит, что произошло
  • Заголовки: метаданные запроса и ответа (например, User-Agent, Content-Type)
  • Тело ответа: обычно HTML (или JSON, если это API)
  • Статус-коды важны для анализа структуры сайта и качества обхода:

  • 200 — успешно
  • 301/302 — редирект (перенаправление)
  • 404 — страница не найдена
  • 429 — слишком много запросов (вы превысили лимиты)
  • 500 — ошибка на стороне сервера
  • Официальная справка по статусам: MDN Web Docs: HTTP response status codes

    Этичный и устойчивый сбор: что нужно учитывать до кода

    Сбор данных легко превратить в «сломать сайт» или «получить бан». Поэтому сразу закладывайте ограничения.

    Практический чек-лист:

  • Проверяйте robots.txt и правила сайта
  • Держите разумную частоту запросов, добавляйте задержку
  • Ставьте timeout, чтобы не зависать
  • Обрабатывайте 429 и 5xx с повторами и паузой
  • Собирайте только то, что реально нужно для задачи
  • Про robots.txt: Google Developers: robots.txt specifications

    HTTP в Python: библиотека requests

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

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

    Минимальный запрос и проверки

    Что важно:

  • timeout обязателен, иначе запрос может зависнуть
  • ловите базовое requests.RequestException, это «зонтик» для сетевых проблем
  • resp.text возвращает текст (requests попробует угадать кодировку)
  • Заголовки: зачем нужен User-Agent

    Многие сайты по-разному реагируют на запросы без нормального User-Agent.

    Практика:

  • не маскируйтесь «под браузер» без необходимости
  • лучше честный User-Agent и умеренная нагрузка
  • Сессия: когда много запросов

    requests.Session() переиспользует соединение и хранит cookies.

    HTML: как устроена страница и что мы из нее извлекаем

    HTML — это дерево элементов (тегов) с атрибутами. Для сбора структуры сайта чаще всего нужно:

  • title страницы
  • h1
  • ссылки (a с атрибутом href)
  • элемент «следующая страница» для пагинации
  • !Упрощенная анатомия HTML-страницы для парсинга

    Парсинг HTML: BeautifulSoup

    Самый популярный инструмент для учебного парсинга — BeautifulSoup.

    Документация: Beautiful Soup Documentation

    Установка:

    Разбор HTML и извлечение простых полей

    Почему везде проверки if soup.title и if href:

  • на реальных страницах часть элементов может отсутствовать
  • ваш код должен возвращать None или пустой список, а не падать
  • CSS-селекторы: точнее и удобнее

    BeautifulSoup поддерживает CSS-селекторы через select.

    Практика:

  • select_one возвращает один элемент или None
  • select возвращает список (может быть пустым)
  • Нормализация ссылок: абсолютные и относительные URL

    Ссылки в HTML могут быть:

  • относительные: /catalog или catalog
  • абсолютные: https://example.com/catalog
  • служебные: mailto:..., tel:..., javascript:...
  • Для сборщика структуры сайта вам обычно нужны только HTTP/HTTPS и только в пределах домена.

    Для склейки относительных ссылок с базовым URL используйте urljoin.

    Документация: urllib.parse.urljoin

    Этот кусок логики отлично тестируется через unittest (как в предыдущей статье).

    Пагинация: как обходить каталоги и списки

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

    Самые частые варианты:

  • параметр в URL: ?page=2 или ?p=2
  • сегмент пути: /catalog/page/2/
  • ссылка «Следующая» внизу страницы
  • В рамках этого курса делаем упор на пагинацию, которая доступна без исполнения JavaScript.

    Паттерн «идем по ссылке Next, пока она есть»

    Идея:

  • скачали страницу списка
  • распарсили ссылки на элементы (товары, статьи)
  • нашли ссылку на следующую страницу
  • повторили
  • Что здесь закрепляется из предыдущих тем:

  • структуры данных: list для результата, set для защиты от повторов
  • циклы и условия: остановка по лимитам и по отсутствию next
  • функции: extract_catalog_page как отдельный шаг пайплайна
  • Мини-архитектура под курс: Fetcher, Parser, Crawler

    Чтобы код было легко расширять, используйте разбиение из статьи про ООП:

  • Fetcher отвечает за HTTP и повторы
  • Parser отвечает за HTML и извлечение данных
  • Crawler отвечает за очередь, visited, лимиты
  • Storage сохраняет JSON
  • Ниже минимальный пример, который собирает страницы пагинации и сохраняет их как список словарей. Он демонстрационный: CSS-селекторы и фильтры вы всегда подстраиваете под конкретный сайт.

    Как это использовать дальше по курсу:

  • catalog_pages.json можно загрузить в pandas через read_json
  • посчитать частоты статусов, глубину URL, число ссылок links_count
  • оценить, насколько полно и корректно вы прошли пагинацию
  • Типовые проблемы и как их диагностировать

  • Пустой HTML или неожиданный контент: проверьте status_code, Content-Type, resp.text[:200]
  • Парсер ничего не находит: селекторы не совпадают с реальной версткой, сначала распечатайте кусок HTML
  • Много дублей ссылок: используйте set для уникальности или drop_duplicates уже в pandas
  • Зацикливание пагинации: храните visited страниц пагинации и ставьте max_pages
  • Блокировки и 429: снижайте частоту, добавляйте паузы, делайте повторы с задержкой
  • Полезные официальные источники

  • Requests: Quickstart
  • Beautiful Soup Documentation
  • urllib.parse (Python Documentation)
  • MDN Web Docs: HTTP response status codes
  • Google Developers: robots.txt specifications
  • 7. Проект: код для извлечения структуры сайта и аналитики данных

    Проект: код для извлечения структуры сайта и аналитики данных

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

  • вы делаете сбор структуры сайта (HTTP → HTML → парсинг ссылок)
  • сохраняете результат в JSON (как делали в темах про файлы)
  • превращаете выгрузку в таблицу и строите аналитику в pandas
  • Идея проекта: на входе у вас один стартовый URL (или несколько), на выходе два артефакта:

  • pages.json — структурированная выгрузка по страницам
  • report/*.csv — итоговые отчеты по статусам, глубине, ссылкам
  • !Общая архитектура проекта и поток данных

    Что именно будем считать «структурой сайта»

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

  • url — абсолютный URL страницы
  • status — HTTP статус-код
  • content_type — чтобы понимать, это HTML или, например, PDF
  • title — из тега title (если есть)
  • h1 — первый h1 (если есть)
  • links — список ссылок со страницы (после фильтрации и нормализации)
  • Этого достаточно, чтобы:

  • найти битые страницы (404, 5xx)
  • оценить покрытие обхода
  • построить аналитику по глубине и связности
  • Зависимости и установка

    В проекте используются библиотеки:

  • requests для HTTP: Requests Documentation
  • beautifulsoup4 для HTML-парсинга: Beautiful Soup Documentation
  • pandas для аналитики: pandas Documentation
  • Установка:

    Структура проекта

    Сделаем простую структуру, чтобы код было легко читать и расширять:

  • site_project/
  • site_project/__init__.py
  • site_project/config.py
  • site_project/url_tools.py
  • site_project/fetcher.py
  • site_project/parser.py
  • site_project/crawler.py
  • site_project/storage.py
  • site_project/analyzer.py
  • main.py
  • Такое разбиение повторяет идею из темы про ООП: компоненты с одной ответственностью.

    Правила «безопасного» обхода

    Чтобы ваш сбор был устойчивым и не вредил сайту:

  • ставьте timeout на запросы
  • делайте паузы между запросами
  • ограничивайте число страниц (max_pages)
  • храните visited, чтобы не зациклиться
  • уважайте правила сайта и robots.txt: robots.txt specifications
  • Модуль config

    site_project/config.py

    Практический смысл полей:

  • max_depth защищает от бесконечного роста очереди
  • allow_query=False часто уменьшает дубли (страницы с ?utm=...)
  • Нормализация и фильтрация ссылок

    site_project/url_tools.py

    Задача этого модуля: привести ссылки к единому виду и отфильтровать мусор.

    Что здесь важно:

  • urljoin правильно склеивает относительные ссылки: urllib.parse.urljoin
  • удаление #fragment почти всегда полезно для структуры сайта
  • Fetcher: HTTP-запросы с таймаутом и обработкой ошибок

    site_project/fetcher.py

    requests.RequestException покрывает сетевые ошибки и таймауты: Requests Exceptions

    Parser: извлечение title, h1 и ссылок из HTML

    site_project/parser.py

    Замечание: BeautifulSoup не исполняет JavaScript. Если сайт «рисуется» JS-ом, ссылки могут не быть видны в HTML.

    Crawler: обход в ширину с depth и visited

    site_project/crawler.py

    Мы будем обходить сайт как граф:

  • узлы графа это страницы
  • ребра графа это ссылки
  • Алгоритм:

  • очередь хранит, что обходить дальше
  • visited защищает от повторов
  • вместе с URL храним depth
  • Почему мы проверяем Content-Type:

  • структура сайта обычно строится по HTML
  • скачивать и парсить как HTML PDF или картинку бессмысленно
  • Storage: сохранение JSON

    site_project/storage.py

    Analyzer: аналитика в pandas и экспорт отчетов

    site_project/analyzer.py

    Считаем полезные отчеты:

  • распределение по status
  • распределение по depth
  • топ страниц по количеству исходящих ссылок
  • список проблемных страниц (status >= 400 или status is None)
  • Если вы хотите дополнить аналитику, следующий логичный шаг:

  • извлечь path и сгруппировать по первому сегменту (/blog/..., /catalog/...)
  • посчитать долю title is null и h1 is null
  • Точка входа main.py

    main.py

    Чтобы протестировать проект на реальном сайте, замените https://example.com/ на свой домен.

    Как интерпретировать результаты

    После запуска у вас появятся:

  • pages.json — сырые результаты (удобно для повторной аналитики)
  • report/pages_cleaned.csv — очищенная таблица
  • report/summary_by_status.csv — сколько страниц каждого статуса
  • report/summary_by_depth.csv — сколько страниц на какой глубине
  • report/top_pages_by_links.csv — страницы с наибольшим числом исходящих ссылок
  • report/problems.csv — ошибки сети и 4xx/5xx
  • Практичные выводы, которые обычно делают по этим файлам:

  • если много status пустой, вероятны таймауты или блокировки
  • если много 3xx, стоит отдельно учитывать редиректы
  • если глубина резко растет, возможно, вы обходите «календарь», фильтры или бесконечную пагинацию
  • Для справки по статусам удобно держать под рукой: HTTP response status codes

    Куда развивать проект дальше

    Когда базовый пайплайн заработал, улучшения обычно идут по таким направлениям:

  • добавить повторы на 429 и 5xx с увеличением паузы
  • сохранять время запроса (fetched_at) и длительность (elapsed_ms) для диагностики
  • добавить режим «только сбор ссылок» без парсинга title/h1
  • хранить граф ссылок и считать входящие ссылки (in-degree) для поиска «важных» страниц
  • добавить тесты на функции нормализации и фильтрации ссылок через unittest: unittest Documentation