не могу спарсить все посты канала

есть код

from telethon.sync import TelegramClient
from telethon import functions, types
import datetime

api_id=API_ID
api_hash='API_TOKEN'

with TelegramClient('name', api_id, api_hash) as client:
    result = client(functions.messages.GetHistoryRequest(
        peer='любой канал',
        offset_id=0, 
        offset_date=0,
        add_offset=0,
        limit=100000,
        max_id=0,
        min_id=0,
        hash=0
    ))
    result=result.messages
    for i in range(len(result)):
        if result[i].message!='':
            nic=result[i].message
            
            print('--------------start-------------------------\n\n')
            print(nic)
            print('------------------end---------------------\n\n')
            
            with open('result.txt', 'ab') as f:
                f.write(nic.encode('utf-8'))
                f.write('\n\n\n'.encode('utf-8'))

Его задача - парсить посты с телеграм каналов, и записывать в текстовик. Но данный код парсит не все посты, а примерно 75 постов. Подскажите пожалуйста, как спарсить весь канал(или до заданного поста). Есть вариант использовать offset_date=datetime.datetime(2020, 12, 10) перебирать в цикле, но тогда посты будут повторяться


Ответы (1 шт):

Автор решения: Arty

Согласно документации можно использовать offset_id параметр для постраничного извлечения всей истории.

Для этого задаём некий относительно небольшой лимит например limit=100 и дальше по 100 штук вычитываем, чтобы запросить следующую страницу просто указываем в offset_id айди последнего сообщения т.е. result[-1].id, после этого будут извлечены посты только идущие "старше" чем пост с заданным айди, т.е. вторая и т.д. страницы.

Полный доработанный код ниже:

from telethon.sync import TelegramClient
from telethon import functions, types
import datetime

api_id=12345
api_hash='API_TOKEN'

with TelegramClient('name', api_id, api_hash) as client:
    limit, cur_id = 100, 0
    while True:
        result = client(functions.messages.GetHistoryRequest(
            peer='любой канал', offset_id=cur_id, offset_date=0,
            add_offset=0, limit=limit, max_id=0, min_id=0, hash=0,
        ))
        result=result.messages
        if len(result) < limit:
            break
        for i in range(len(result)):
            if result[i].message!='':
                nic=result[i].message
                
                print('--------------start-------------------------\n\n')
                print(nic)
                print('------------------end---------------------\n\n')
                
                with open('result.txt', 'ab') as f:
                    f.write(nic.encode('utf-8'))
                    f.write('\n\n\n'.encode('utf-8'))
        cur_id = result[-1].id
→ Ссылка