Для парсинга сообщений из группы или паблика Telegram используется два основных метода библиотеки Telethon.
.get_messages() возвращает указанное количество сообщений чата.
.iter_messages() совершает итерации по каждому сообщению отдельно.
У каждого из этих методов есть свои плюсы и минусы. Рассмотрим эти два метода более подробно.
Метод client.get_messages() — аналогично функции iter_messages(), но вместо итератора возвращается список TotalList. Если limit не задан, по умолчанию будет равно 1, если только не заданы min_id и max_id (в качестве именованных аргументов), в этом случае будет возвращен весь диапазон. Это сделано потому, что любое целочисленное ограничение было бы довольно произвольным, и обычно требуется получить только одно сообщение, но если задан диапазон, то логично, что он должен возвращать его целиком. Если ids присутствует в именованных аргументах и не является списком, то для удобства вместо списка будет возвращено одно сообщение.
Метод client.iter_messages() — возвращает асинхронный итератор, который позволяет последовательно получать сообщения из чата или канала. Если параметр limit=None — метод не ограничивает количество сообщений и возвращает все доступные сообщения, соответствующие указанным фильтрам. Параметр from_user=user_id ограничивает итерацию только сообщениями, отправленными указанным пользователем, соответственно, если пользователь отправил всего 3 сообщения, именно они и будут получены.
Пример кода:
from telethon import TelegramClient, events, sync, connection
r_api = 1111
r_hash = ''
with TelegramClient('my', r_api, r_hash, system_version="4.10.5 beta x64") as client:
all_message = client.get_messages('https://t.me/name_group')
for message in all_message:
print(message)
Содержимое ответа:
Message(
id=200, - идентификатор этого сообщения;
peer_id=
PeerChannel(
channel_id=1795821154), - ID пользователя, группы, канала, куда было отправлено сообщение;)
date=
datetime.datetime(2022, 6, 11, 9, 40, 26, tzinfo=datetime.timezone.utc), - объект даты, когда сообщение было отправлено;
message='Текст сообщения', - строковый объект сообщения;
out=False, - возвращает True, если сообщение является исходящим, т.е., отправлено с вашей учетной записи;
mentioned=False, - возвращает True, если, вы были упомянуты в этом сообщении;
media_unread=False, - возвращает True, если медиа в сообщении не были прочитаны;
silent=False, - возвращает True, если уведомления отключены;
post=False, - возвращает True, если сообщение является постом в широковещательном канале;
from_scheduled=False, - возвращает True, если сообщение было создано из заранее запланированного сообщения;
legacy=False, - возвращает True, если сообщение является устаревшим;
edit_hide=False, - возвращает True, если метка о редактировании сообщения была скрыта;
pinned=False, - возвращает True, если сообщение закреплено в настоящее время;
from_id=
PeerUser(
user_id=1115814085), - ID пользователя, группы или канала отправившего сообщение;
fwd_from=None, - возвращает True, если сообщение является репостом из другого чата\группы\паблика;
via_bot_id=None, - ID бота который отправлял это сообщение;
reply_to=None, - ID сообщения если это сообщение отвечает на другое;
media=None, - медиафайлы отправленные в сообщении если такие имеются(фото, видео, документы, GIF, стикеры и т.д)
reply_markup=None, - разметка для этого сообщения, которое отправлено ботом, чаще всего это кнопки;
entities=[], - список элементов в этом сообщении, таких как жирный шрифт, курсив, код, гиперссылки и т.д.;
views=None, - количество просмотров этого сообщения;
forwards=None, - сколько раз это сообщение было переадресовано;
replies= - сколько раз другое сообщение ответило на это сообщение;
MessageReplies(
replies=0,
replies_pts=213,
comments=False,
recent_repliers=[],
channel_id=None,
max_id=None,
read_max_id=None),
edit_date=None, - дата последнего редактирования сообщения;
post_author=None, - отображаемое имя отправителя сообщения;
grouped_id=None, - проверяет, принадлежит ли это сообщение к группе сообщений, фото- или видео альбому;
restriction_reason=[], - список причин, по которым это сообщение было ограничено;
ttl_period=None - период жизни, настроенный для этого сообщения;)
Запоминать все поля возвращаемого объекта не нужно, для парсинга нам чаще всего необходимы следующие поля с информацией:
user_id — чтобы извлечь ID пользователя, отправившего сообщение, необходимо к объекту сообщения применить способ
message.from_id.user_id;
date — для того, чтобы извлечь дату отправки сообщения, используется способ message.date;
message — чтобы извлечь текст сообщения, применяется два способа, message.text и message.message;
media — используется для определения, присутствуют ли медиафайлы в сообщении или нет, как извлекать медиафайлы из сообщения мы поговорим далее;
Доступ к остальным полям осуществляется подобным образом, с этим проблем у вас возникнуть не должно.
Обратите внимание на один важный момент. В объекте Message, хранится user_id в цифровом формате, а нам чаще всего необходимо знать его username, если он у него имеется. Чтобы конвертировать user_id в username используется метод .get_entity(ID). Функция .get_entity(ID) возвращает объект User со всеми соответствующими этому объекту полями.
Выполнение функции .get_entity(ID) вернет объект, у которого имеются все необходимые поля, нам осталось извлечь из них username.
Код ниже, получает первое сообщение в чате, извлекает из него user_id (message.from_id.user_id) и передает его в функцию .get_entity(ID) которая возвращает объект User, и уже у этого объекта мы извлекаем username.
from telethon import TelegramClient, events, sync, connection
r_api = 1111
r_hash = ''
with TelegramClient('my', r_api, r_hash) as client:
all_message = client.get_messages('https://t.me/name_group')
for message in all_message:
id_user = message.from_id.user_id
print(client.get_entity(id_user).username)