Парсим данные в Telegram на Python. Часть 2. Читаем и анализируем сообщения из чатов
Пишем парсер для Telegram: собираем сообщения из каналов и чатов.
Иллюстрация: Катя Павловская для Skillbox Media
Сегодня мы научимся парсить чаты из Telegram: разберёмся в том, какие модули нам пригодятся, и настроим сбор сообщений. Всё это с помощью библиотеки Telethon для Python.
Это второй урок по парсингу в Telegram. В первом мы создали парсер списка участников каналов и чатов и научились работать с инструментами разработчика API мессенджера. Если вы ещё не читали первую часть, то обязательно начните с неё.
Что у нас сейчас есть?
В первой части урока мы:
- настроили инструменты разработчика API Telegram и научились использовать их для подключения к клиенту мессенджера;
- установили и импортировали библиотеку Telethon, позволяющую работать с API Telegram, выбрав нужные нам классы, функции и типы;
- научились парсить список групп и чатов из мессенджера;
- написали код для парсинга списка пользователей в чате или мессенджере, сохраняющий их в удобном для чтения и последующего анализа виде.
У нас остаётся одна задача — спарсить сообщения из чатов. Мы сохраним только содержание чатов без дополнительной информации о времени их отправки и самом отправителе. В дальнейшем эти данные можно будет использовать для анализа переписки: например, узнать о самых часто встречающихся словах и предположить самые популярные темы для обсуждения.
Добавляем новые импорты
Откроем в IDE код из первой части урока. Мы продолжим работать с ним, а не будем писать всё с нуля. Чтобы спарсить сообщения из чатов, необходимо импортировать новый метод и функцию в начало кода:
Что мы импортировали:
- GetHistoryRequest — метод, позволяющий получить сообщения пользователей из чата и работать с ним;
- PeerChannel — специальный тип, определяющий объекты типа «канал/чат», с помощью которого можно обратиться к нужному каналу для парсинга сообщений.
Пишем код парсера сообщений
Начнём с создания пустого списка, который будет хранить сообщения, и инициализируем несколько переменных, которые пригодятся позже.
Список all_messages используется для хранения спарсенных сообщений. Переменная limit задаёт лимит на парсинг сообщений — за каждый цикл работы будет сохраняться только 100 сообщений.
Кроме того, мы используем ещё две переменные — total_messages и total_count_limit. Первая выступает счётчиком спарсенных сообщений, а вторая позволят нам задать ограничение на общее количество полученных сообщений. В примере кода total_count_limit равен 0, то есть парсятся все сообщения. Если история чата большая, то её парсинг может занять слишком много времени. В этом случае можно ограничить количество спарсенных сообщений вручную.
offset_id — важная переменная. К ней будет обращаться метод GetHistoryRequest для того, чтобы понять, с какого сообщения начать парсинг. Вначале присваиваем ей значение 0, чтобы парсинг шёл с самого первого сообщения в канале. То есть если бы мы указали значение, равное 100, то первые 100 сообщений парсер бы пропустил.
Добавим в код сам парсер сообщений и разберём его:
Парсинг реализуется через цикл while. Код в цикле будет выполняться до тех пор, пока в чате остаются сообщения, которые мы ещё не спарсили, или пока не будет достигнут установленный лимит по числу собранных сообщений.
Для получения сообщений используем стандартный метод библиотеки Telethon — GetHistoryRequest, передавая его внутри запроса нашего клиента к API Telegram. Для выбора группы используется параметр peer, которому мы присваиваем значение выбранной группы, полученной в начале работы парсера. В нашем случае это другая переменная — target_group.
Параметры offset_date и offset_peer мы передаём с пустыми значениями. Обычно они используются для фильтрации полученных данных, но здесь мы хотим получить весь список сообщений. Лимит по количеству элементов в ответе задаём числом 100, передавая в параметр limit переменную limit. Также у нас есть три обязательных параметра для работы GetHistoryRequest: min_id, max_id и hash. Их передаём с нулевыми значениями, так как они не будут использоваться, но указать их обязательно — если этого не сделать, метод не будет работать.
Основной цикл работает просто:
- Проверяем, остаются ли сообщения, которые можно спарсить. Если нет, то цикл завершается. Если сообщения есть, то сохраняем их в список messages.
- Каждое сообщение из списка message мы сохраняем в список all_messages.
- Если количество полученных сообщений больше их количества в чате или мы достигли лимита парсинга, то цикл завершается.
GetHistoryRequest получает offset_id, который показывает, с какого сообщения GetHistoryRequest должен начать получать историю чата. Важно правильно установить смещение для offset_id, чтобы все сообщения были уникальными. Поэтому стартовое значение offset_id для следующего прохождения цикла устанавливается со смещением на одно сообщение.
Сохраняем полученные сообщения в файл
Полученные сообщения сохраняем в формате CSV по аналогии с парсингом пользователей:
После этого переходим к сохранению данных в файл формата CSV с помощью стандартного модуля csv. Открываем файл в режиме записи, указывая кодировку UTF-8.
Если файл отсутствует в директории, то будет в ней создан. После этого создаём объект CSV writer и записываем в него сообщение из нашего списка all_messages.
Запустим парсер и выберем группу из списка:
Всё получилось. Откроем нашу директорию. Теперь в ней два файла в формате CSV: members.csv и chats.csv. Откроем последний:
Мы видим, что сохранились не только сами сообщения, но и техническая информация про их id, id запроса и так далее. Такой результат нам не подходит. Вернёмся к циклу while и добавим к методу message параметр message. Он позволяет сохранять только само сообщение.
Повторно запустим код и посмотрим на результат:
Теперь всё работает как надо. Сохранились только сообщения без служебной информации о запросах.
Код парсера для Telegram на Python полностью
В двух частях урока по парсингу информации из Telegram мы написали много кода. Посмотрим на него полностью:
Что дальше?
Библиотека Telethon используется не только для парсинга информации о пользователях и сообщений в каналах и чатах, но и для автоматизации работы с Telegram. Например, администраторы каналов могут создать бота, позволяющего писать сообщения, отправлять стикеры и управлять списком участников. Эти примеры разобраны в документации библиотеки.