Как можно сохранить несколько медиафайлов при парсинге канала с помощью библиотеки Telethon?

Как можно изменить функциональность моего бота-автопостера и парсера, чтобы он сохранял последний пост из указанного канала на компьютер и публиковал его в списке каналов, указанном в файле channels.json? В настоящее время мой парсер сохраняет только одно медиа и текст, и если сообщение содержит больше одного медиа, он загружает только одно фото или видео, а текст не сохраняется. 

Вот код парсера: 
<pre><code class="python">import os
import json
from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError
from telethon.tl.types import MessageMediaPhoto, MessageMediaDocument  # Убираем все устаревшие импорты
from config import API_ID, API_HASH, PHONE_NUMBER, ADMIN_ID
from handlers.logging import log_error, log_action  # Импортируем логирование

# Загружаем данные из last_post.json
def load_last_post():
    """Загружает данные о последнем посте из файла"""
    try:
        with open('data/last_post.json', 'r', encoding='utf-8') as file:
            data = json.load(file)
            print("Загружены данные о последнем посте:", data)  # Для отладки
            return data
    except Exception as e:
        print(f"Ошибка при загрузке данных о последнем посте: {e}")
        return {"channels": {}}

# Сохраняем данные в last_post.json
def save_last_post(data):
    """Сохраняет данные в last_post.json"""
    with open('data/last_post.json', 'w', encoding='utf-8') as file:
        json.dump(data, file, ensure_ascii=False, indent=4)

async def process_message(message, client, channel_folder):
    """Обработка сообщения, извлечение текста и медиа."""
    message_data = {
        'message_id': message.id,
        'text': "Без текста",  # Начальная установка, если текст не н
  • 1 декабря 2024 г. 14:53
Ответы на вопрос 2
Чтобы изменить функциональность вашего бота парсера на Telethon так, чтобы он сохранял все медиафайлы и текст последнего поста, а затем публиковал его на указанных каналах из `channels.json`, вам нужно внести несколько изменений в ваш код.

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

```python
import os
import json
from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError
from telethon.tl.types import MessageMediaPhoto, MessageMediaDocument, MessageMediaVideo
from config import API_ID, API_HASH, PHONE_NUMBER, ADMIN_ID
from handlers.logging import log_error, log_action

# Загружаем данные из last_post.json
def load_last_post():
    """Загружает данные о последнем посте из файла"""
    try:
        with open('data/last_post.json', 'r', encoding='utf-8') as file:
            data = json.load(file)
            print("Загружены данные о последнем посте:", data)  # Для отладки
            return data
    except Exception as e:
        print(f"Ошибка при загрузке данных о последнем посте: {e}")
        return {"channels": {}}

# Сохраняем данные в last_post.json
def save_last_post(data):
    """Сохраняет данные в last_post.json"""
    with open('data/last_post.json', 'w', encoding='utf-8') as file:
        json.dump(data, file, ensure_ascii=False, indent=4)

async def process_message(message, client, channel_folder):
    """Обработка сообщения, извлечение текста и медиа."""
    message_data = {
        'message_id': message.id,
        'text': message.message if message.message else "Без текста",
        'media_files': []  # Список для сохранения медиафайлов
    }

    # Обработка медиа
    if message.media:
        # Получаем тип медиа и обрабатываем соответствующим образом
        if isinstance(message.media, (MessageMediaPhoto, MessageMediaVideo, MessageMediaDocument)):
            media_file = await client.download_media(message.media, file=channel_folder)
            if media_file:
                message_data['media_files'].append(media_file)

    # Сохраняем данные о сообщении
    save_last_post(message_data)

    return message_data

async def main():
    # Ваш код инициализации клиента и получения канала
    async with TelegramClient('session_name', API_ID, API_HASH) as client:
        # Ваш код для получения канала и обработки сообщений
        channel = 'username_of_the_channel'
        channel_folder = 'data/' + channel.replace('@', '')
        os.makedirs(channel_folder, exist_ok=True)

        # Пример получения последнего сообщения из канала
        last_message = await client.get_messages(channel, limit=1)
        if last_message:
            await process_message(last_message[0], client, channel_folder)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())
```

### Что было изменено:

1. **Сохранение текста сообщения**: Теперь текст сообщений сохраняется, даже если его нет — в этом случае используется значение "Без текста".

2. **Сохранение медиафайлов**: Добавлен список `media_files`, в который сохраняются все загруженные медиафайлы. 

3. **Загрузка всех типов медиа**: Проверяется, является ли `message.media` одним из типов медиа, и в случае успеха загружается медиа и добавляется в список `media_files`.

### Дополнительно
Вы можете также добавить логику для последующей публикации загруженных медиафайлов в каналы, указанные в `channels.json`. Для этого необходимо:

- Загрузить список каналов из файла `channels.json`.
- Реализовать функцию, которая будет отправлять сообщение (включая текст и медиафайлы) в эти каналы.

Если у вас есть вопросы по реализации этой функциональности, не стесняйтесь обращаться!
В ТГ сообщение с несколькими медиафайлами, медиа приходят по сути разными сообщениями и соответственно у тебя проблема с тем что получается парсить только текст с одним медиа потому что на один объект сообщения можно закрепить одно фото. Чтобы сгруппировать фото из одного альбома, ты можешь использовать параметр grouped_id и с помощью него корректно сформировать медиа-группу и спарсить сообщение с несколькими медиа. 
Для того чтобы было более понятно, оставил пример кода как достать значение параметра.
from telethon import TelegramClient
api_id = 11111111
api_hash = ''
client = TelegramClient('123', api_id, api_hash)

async def main():
    msgs = await client.get_messages(-10000000000, limit=2)
    print(msgs[0])
    print(msgs[0].grouped_id)
    print(msgs[1].grouped_id)

with client:
    client.loop.run_until_complete(main())


Также если будешь реализовывать бота через прослушивание, то ниже закрепил код для того чтобы сразу одним объектом получать такие альбомы.
from telethon import events

@client.on(events.Album)
async def handler(event):
    # Counting how many photos or videos the album has
    print('Got an album with', len(event), 'items')

    # Forwarding the album as a whole to some chat
    event.forward_to(chat)

    # Printing the caption
    print(event.text)

    # Replying to the fifth item in the album
    await event.messages[4].reply('Cool!')
Похожие вопросы