Telegram User-бот для парсинга группы: сбор данных и аналитика

Telegram User-боты отлично подходят для парсинга (сбора данных) из Telegram-групп и каналов. В отличие от обычных ботов, user-боты могут читать все сообщения в группах, собирать статистику участников и анализировать активность.

Зачем нужен парсинг групп?

1. Сбор статистики и аналитики

    • Подсчет количества сообщений от каждого участника
    • Анализ активности группы по времени
    • Сбор метрик популярности контента
    • Отслеживание роста участников

2. Мониторинг контента

    • Сбор всех сообщений из группы
    • Поиск сообщений по ключевым словам
    • Экспорт истории группы
    • Анализ типов контента (текст, медиа, ссылки)

3. Исследование и анализ

    • Изучение поведения участников
    • Анализ популярных тем обсуждений
    • Сбор данных для исследований
    • Мониторинг конкурентов

Что мы создадим?

В этом руководстве мы создадим User-бота для парсинга Telegram-группы, который будет выполнять следующие задачи: Задачи бота:
    • Собирать все сообщения из группы с сохранением в базу данных
    • Собирать информацию об участниках группы
    • Подсчитывать статистику активности каждого участника
    • Экспортировать данные в CSV и JSON форматы
    • Фильтровать сообщения по ключевым словам
    • Собирать медиа-файлы из группы
Что мы получим: Полнофункциональный инструмент для сбора и анализа данных из Telegram-групп, который поможет вам понять активность участников, популярные темы и динамику развития группы.

Шаг 1: Получение API credentials

Для работы User-бота нужны API credentials от Telegram. Если вы еще не получили их, сделайте следующее:
    • Перейдите на https://my.telegram.org/
    • Авторизуйтесь своим номером телефона
    • Перейдите в раздел "API development tools"
    • Создайте новое приложение
    • Сохраните api_id и api_hash
Важно: Никогда не публикуйте эти данные в открытом доступе!

Шаг 2: Установка библиотек

Для нашего бота парсера понадобятся следующие библиотеки:
pip install telethon pandas
    • telethon — для работы с Telegram API
    • pandas — для работы с данными и экспорта в CSV

Шаг 3: Создание базы данных

Создайте файл database.py для работы с базой данных:
import sqlite3
from datetime import datetime

class Database:
    def __init__(self, db_name='group_parser.db'):
        self.conn = sqlite3.connect(db_name)
        self.create_tables()
    
    def create_tables(self):
        cursor = self.conn.cursor()
        
        # Таблица участников
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY,
                user_id INTEGER UNIQUE,
                username TEXT,
                first_name TEXT,
                last_name TEXT,
                phone TEXT,
                is_bot INTEGER DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # Таблица сообщений
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS messages (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                message_id INTEGER,
                user_id INTEGER,
                chat_id INTEGER,
                text TEXT,
                date TIMESTAMP,
                is_reply INTEGER DEFAULT 0,
                reply_to_message_id INTEGER,
                media_type TEXT,
                media_file_id TEXT,
                views INTEGER DEFAULT 0,
                forwards INTEGER DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users (user_id)
            )
        ''')
        
        # Таблица статистики
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS statistics (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                total_messages INTEGER DEFAULT 0,
                total_media INTEGER DEFAULT 0,
                total_links INTEGER DEFAULT 0,
                last_activity TIMESTAMP,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users (user_id)
            )
        ''')
        
        self.conn.commit()
    
    def add_user(self, user_id, username=None, first_name=None, last_name=None, phone=None, is_bot=False):
        cursor = self.conn.cursor()
        cursor.execute('''
            INSERT OR REPLACE INTO users (user_id, username, first_name, last_name, phone, is_bot)
            VALUES (?, ?, ?, ?, ?, ?)
        ''', (user_id, username, first_name, last_name, phone, is_bot))
        self.conn.commit()
    
    def add_message(self, message_id, user_id, chat_id, text, date, is_reply=False, reply_to=None, media_type=None, media_file_id=None, views=0, forwards=0):
        cursor = self.conn.cursor()
        cursor.execute('''
            INSERT INTO messages (message_id, user_id, chat_id, text, date, is_reply, reply_to_message_id, media_type, media_file_id, views, forwards)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (message_id, user_id, chat_id, text, date, is_reply, reply_to, media_type, media_file_id, views, forwards))
        self.conn.commit()
    
    def update_statistics(self, user_id, total_messages=0, total_media=0, total_links=0):
        cursor = self.conn.cursor()
        cursor.execute('''
            INSERT OR REPLACE INTO statistics (user_id, total_messages, total_media, total_links, last_activity)
            VALUES (?, 
                COALESCE((SELECT total_messages FROM statistics WHERE user_id = ?), 0) + ?,
                COALESCE((SELECT total_media FROM statistics WHERE user_id = ?), 0) + ?,
                COALESCE((SELECT total_links FROM statistics WHERE user_id = ?), 0) + ?,
                CURRENT_TIMESTAMP
            )
        ''', (user_id, user_id, total_messages, user_id, total_media, user_id, total_links))
        self.conn.commit()
    
    def get_all_messages(self):
        cursor = self.conn.cursor()
        cursor.execute('''
            SELECT m.*, u.username, u.first_name 
            FROM messages m 
            LEFT JOIN users u ON m.user_id = u.user_id 
            ORDER BY m.date DESC
        ''')
        return cursor.fetchall()
    
    def get_user_statistics(self):
        cursor = self.conn.cursor()
        cursor.execute('''
            SELECT u.user_id, u.username, u.first_name, 
                   s.total_messages, s.total_media, s.total_links, s.last_activity
            FROM statistics s
            JOIN users u ON s.user_id = u.user_id
            ORDER BY s.total_messages DESC
        ''')
        return cursor.fetchall()
    
    def close(self):
        self.conn.close()

Шаг 4: Создание парсера

Создайте файл group_parser_bot.py:
from telethon import TelegramClient, events
import asyncio
import os
from datetime import datetime
import re
from database import Database

Данные из my.telegram.org

API_ID = 12345678 # Замените на ваш api_id API_HASH = 'your_api_hash_here' # Замените на ваш api_hash

ID группы для парсинга (можно получить через @userinfobot)

GROUP_ID = -1001234567890 # Замените на ID вашей группы

Создаем клиент

client = TelegramClient('parser_bot_session', API_ID, API_HASH)

Инициализируем базу данных

db = Database('parsed_group.db')

Счетчики для статистики

stats = { 'messages_parsed': 0, 'users_found': 0, 'media_files': 0, 'links_found': 0 }

Функция для извлечения ссылок из текста

def extract_links(text): if not text: return [] url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+' return re.findall(url_pattern, text)

Функция для определения типа медиа

def get_media_type(message): if message.photo: return 'photo' elif message.video: return 'video' elif message.document: return 'document' elif message.audio: return 'audio' elif message.voice: return 'voice' elif message.sticker: return 'sticker' elif message.gif: return 'gif' return None

Обработчик новых сообщений в группе

@client.on(events.NewMessage(chats=GROUP_ID)) async def parse_message(event): message = event.message sender = await event.get_sender() # Сохраняем информацию об участнике if sender: db.add_user( user_id=sender.id, username=sender.username, first_name=sender.first_name, last_name=sender.last_name, phone=getattr(sender, 'phone', None), is_bot=getattr(sender, 'bot', False) ) stats['users_found'] += 1 # Извлекаем данные из сообщения text = message.text or message.raw_text or '' message_id = message.id date = message.date is_reply = message.reply_to is not None reply_to_id = message.reply_to.reply_to_msg_id if is_reply else None # Определяем тип медиа media_type = get_media_type(message) media_file_id = None if media_type: stats['media_files'] += 1 if message.photo: media_file_id = message.photo.id elif hasattr(message, 'file') and message.file: media_file_id = message.file.id # Извлекаем ссылки links = extract_links(text) links_count = len(links) stats['links_found'] += links_count # Получаем статистику просмотров и пересылок views = getattr(message, 'views', 0) or 0 forwards = getattr(message, 'forwards', 0) or 0 # Сохраняем сообщение в базу db.add_message( message_id=message_id, user_id=sender.id if sender else 0, chat_id=GROUP_ID, text=text, date=date, is_reply=is_reply, reply_to=reply_to_id, media_type=media_type, media_file_id=media_file_id, views=views, forwards=forwards ) # Обновляем статистику участника if sender: db.update_statistics( user_id=sender.id, total_messages=1, total_media=1 if media_type else 0, total_links=links_count ) stats['messages_parsed'] += 1 # Выводим прогресс каждые 100 сообщений if stats['messages_parsed'] % 100 == 0: print(f"📊 Обработано сообщений: {stats['messages_parsed']}") print(f"👥 Участников: {stats['users_found']}") print(f"📎 Медиа-файлов: {stats['media_files']}") print(f"🔗 Ссылок: {stats['links_found']}") print("---")

Функция для парсинга истории группы (все сообщения)

async def parse_group_history(): """Парсит всю историю группы с самого начала""" print(f"🔄 Начинаю парсинг истории группы {GROUP_ID}...") try: messages_count = 0 async for message in client.iter_messages(GROUP_ID, limit=None): # Обрабатываем сообщение через наш обработчик event = type('Event', (), { 'message': message, 'get_sender': lambda: client.get_entity(message.sender_id) if message.sender_id else None })() # Имитируем событие для обработчика sender = await event.get_sender() if message.sender_id else None # Сохраняем участника if sender: db.add_user( user_id=sender.id, username=sender.username, first_name=sender.first_name, last_name=sender.last_name, phone=getattr(sender, 'phone', None), is_bot=getattr(sender, 'bot', False) ) # Извлекаем данные text = message.text or message.raw_text or '' media_type = get_media_type(message) links = extract_links(text) # Сохраняем сообщение db.add_message( message_id=message.id, user_id=sender.id if sender else 0, chat_id=GROUP_ID, text=text, date=message.date, is_reply=message.reply_to is not None, reply_to=message.reply_to.reply_to_msg_id if message.reply_to else None, media_type=media_type, media_file_id=None, views=getattr(message, 'views', 0) or 0, forwards=getattr(message, 'forwards', 0) or 0 ) # Обновляем статистику if sender: db.update_statistics( user_id=sender.id, total_messages=1, total_media=1 if media_type else 0, total_links=len(links) ) messages_count += 1 if messages_count % 100 == 0: print(f"✅ Обработано сообщений из истории: {messages_count}") print(f"✨ Парсинг завершен! Всего обработано: {messages_count} сообщений") except Exception as e: print(f"❌ Ошибка при парсинге истории: {e}")

Функция экспорта данных

def export_to_csv(): """Экспортирует данные в CSV файлы""" import csv from datetime import datetime # Экспорт сообщений messages = db.get_all_messages() with open(f'messages_export_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['ID', 'Message ID', 'User ID', 'Username', 'First Name', 'Text', 'Date', 'Media Type', 'Views', 'Forwards']) for msg in messages: writer.writerow(msg) # Экспорт статистики stats_data = db.get_user_statistics() with open(f'statistics_export_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['User ID', 'Username', 'First Name', 'Total Messages', 'Total Media', 'Total Links', 'Last Activity']) for stat in stats_data: writer.writerow(stat) print("📁 Данные экспортированы в CSV файлы")

Запуск бота

async def main(): await client.start() print("🤖 Бот-парсер запущен!") print(f"📊 Парсинг группы: {GROUP_ID}") print("\nВыберите режим работы:") print("1. Парсинг только новых сообщений (режим реального времени)") print("2. Парсинг всей истории группы") print("3. Экспорт данных в CSV") # В реальном приложении можно добавить интерактивный выбор # Для примера запускаем парсинг истории choice = input("\nВведите номер (1-3): ").strip() if choice == '1': print("🔄 Режим реального времени активирован. Ожидаю новые сообщения...") await client.run_until_disconnected() elif choice == '2': await parse_group_history() export_to_csv() elif choice == '3': export_to_csv() else: print("Неверный выбор. Запускаю режим реального времени...") await client.run_until_disconnected() db.close() if __name__ == '__main__': asyncio.run(main())

Шаг 5: Дополнительные функции

Фильтрация сообщений по ключевым словам

Добавьте в обработчик сообщений:
# Ключевые слова для фильтрации
KEYWORDS = ['важное', 'новости', 'объявление']

В функции parse_message после сохранения сообщения:

if any(keyword.lower() in text.lower() for keyword in KEYWORDS): print(f"🔔 Найдено сообщение с ключевым словом: {text[:100]}") # Можно отправить уведомление или сохранить в отдельную таблицу

Сбор участников группы

Добавьте функцию для получения списка всех участников:
async def collect_group_members():
    """Собирает информацию обо всех участниках группы"""
    print("👥 Собираю список участников группы...")
    
    participants = []
    async for user in client.iter_participants(GROUP_ID):
        db.add_user(
            user_id=user.id,
            username=user.username,
            first_name=user.first_name,
            last_name=user.last_name,
            phone=getattr(user, 'phone', None),
            is_bot=getattr(user, 'bot', False)
        )
        participants.append({
            'id': user.id,
            'username': user.username,
            'name': f"{user.first_name} {user.last_name or ''}".strip()
        })
    
    print(f"✅ Собрано участников: {len(participants)}")
    return participants

Экспорт в JSON

Добавьте функцию экспорта в JSON:
import json

def export_to_json():
    """Экспортирует данные в JSON файл"""
    messages = db.get_all_messages()
    stats = db.get_user_statistics()
    
    data = {
        'messages': [
            {
                'id': msg[0],
                'message_id': msg[1],
                'user_id': msg[2],
                'username': msg[8],
                'text': msg[4],
                'date': msg[5].isoformat() if msg[5] else None,
                'media_type': msg[9]
            }
            for msg in messages
        ],
        'statistics': [
            {
                'user_id': stat[0],
                'username': stat[1],
                'total_messages': stat[3],
                'total_media': stat[4],
                'total_links': stat[5]
            }
            for stat in stats
        ]
    }
    
    filename = f'export_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    
    print(f"📁 Данные экспортированы в {filename}")

Безопасность и ограничения

Важные моменты:

    • Соблюдайте правила Telegram — не нарушайте Terms of Service
    • Уважайте приватность — не распространяйте собранные данные без разрешения
    • Соблюдайте лимиты API — добавляйте задержки между запросами
    • Храните данные безопасно — шифруйте базу данных при необходимости

Рекомендации:

    • Добавьте задержки при парсинге больших групп
    • Ограничьте количество запросов в секунду
    • Регулярно делайте бэкапы базы данных
    • Используйте виртуальное окружение Python

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

    • Запустите бота:
python group_parser_bot.py
    • Выберите режим парсинга:
- Режим 1: мониторинг новых сообщений в реальном времени - Режим 2: парсинг всей истории группы - Режим 3: экспорт уже собранных данных
    • Результаты:
- База данных SQLite с собранными данными - CSV файлы с экспортированными данными - Статистика по активности участников

Заключение

User-бот для парсинга групп — это мощный инструмент для сбора и анализа данных из Telegram. Он позволяет автоматизировать процесс сбора информации, анализировать активность участников и экспортировать данные для дальнейшего анализа. Помните о приватности и правилах использования. Используйте парсинг ответственно и только для законных целей.
Полезные ресурсы:

2414 просмотров
0 лайков
0 комментариев