telethon查询组内成员-iter_participants
iter_participants
可以在文档中搜索此方法
关于iter_participants
iter_participants
是 Telethon 库中一个用来获取某个聊天(如频道、群组等)中的所有参与者(用户)信息的迭代器。它可以逐个返回指定聊天中的用户,通常用在需要获取大规模用户信息时。
方法签名
iter_participants(entity: hints.EntityLike, limit: float = None, *, search: str = '', filter: types.TypeChannelParticipantsFilter = None, aggressive: bool = False)
参数说明:
- entity: 这是你想获取参与者的聊天实体。
entity
可以是一个chat
的 ID 或者一个User
对象,表示你要查询的聊天。比如,可以是某个频道、群组的对象或其 ID。 - limit: 这是你希望获取的最大参与者数量。比如,设置为
100
则表示最多返回 100 个参与者。若未指定,默认为None
,意味着没有限制。 - search: 这是一个字符串,允许你根据用户名称进行筛选。只有用户名称中包含该字符串的用户才会被返回。例如,设置为
"john"
可能会返回所有用户名中包含 "john" 的参与者。 - filter: 这是一个可选参数,允许你指定对参与者进行进一步筛选的条件。Telethon 提供了几种内建的筛选器类型(如
FilterAdmins
、FilterBots
等)。这些筛选器可以帮助你只获取特定类型的用户,比如只获取管理员或机器人等。 - aggressive: 默认为
False
,是否在遍历参与者时更加“激进”地去获取更多的用户。这个参数的具体作用是如何控制请求的行为,通常用于大量用户的场景。
返回值:
- 该方法返回一个
_ParticipantsIter
对象,这是一个迭代器,你可以通过迭代这个对象来获取每一个参与者的详细信息。
作用:
iter_participants
用于从一个指定的聊天中逐个获取所有参与者的信息。这个方法非常适合需要处理大量聊天成员数据的场景,比如你想要获取一个大型群组的所有成员信息,或者筛选某个频道中的管理员、成员等。- 函数文档中的“顺序未指定”意味着返回的用户列表没有特定的顺序。返回的参与者顺序可能会因为 Telegram 服务器的变化或其他因素而有所不同。你不应该依赖顺序来处理数据。
用法
from telethon.sync import TelegramClient
from telethon.tl.types import PeerChannel
# 假设你已经正确设置并连接到 Telegram Client
client = TelegramClient('session_name', api_id, api_hash)
# 获取某个频道的所有成员
entity = PeerChannel(channel_id) # 你可以替换为频道的 ID 或者 Channel 对象
participants = client.iter_participants(entity, limit=100)
# 输出每个参与者的信息
for participant in participants:
print(participant.username, participant.id)
总结
iter_participants
是一个非常有用的函数,能够帮助你从一个指定的 Telegram 聊天(群组或频道)中获取所有参与者的信息。你可以控制获取的数量、筛选特定用户(如管理员、机器人等)以及根据用户名进行搜索等。返回的结果顺序不固定,适用于你需要迭代和处理大量数据的场景。
PeerChannel
关于PeerChannel,请查看:
https://czjdwy.xyz/index.php/archives/15/
异步生成器
按需拉取数据
iter_participants
是一种懒加载机制,它不会一次性加载所有成员到内存,而是在迭代时根据需要从 Telegram API 分页获取数据。这对于大群组(成员数量可能达几千或更多)非常重要,可以避免:- 内存占用过高
- API 超时
- 数据获取不完整
- 分页自动处理
async for
的每次循环会触发生成器内部发送请求并接收一批成员数据,直到所有数据获取完成。您不需要手动处理分页(比如计算offset
),生成器会帮您完成这些工作。 控制逻辑
使用async for
允许在每次获取数据后插入控制逻辑,例如:- 动态延迟(
await asyncio.sleep(delay)
),防止触发速率限制。 - 处理异常(如
FloodWaitError
)。 - 逐步处理成员数据,避免一次性加载所有数据到内存。
- 动态延迟(
在 participants = client.iter_participants(entity)
中,participants
是一个生成器,它还没有真正获取数据,只有在 async for
中逐步迭代时才会真正拉取成员数据。因此,async for
是关键,它不仅负责触发数据拉取,还允许您动态控制和处理数据,从而提高代码的灵活性和效率。
entity = PeerChannel(11111111)
participants = client.iter_participants(entity, limit=100)
all_members = []
try:
async for participant in participants:
print(f"ID: {participant.id}, 用户名: {participant.username}")
all_members.append(participant)
await asyncio.sleep(2) # 动态延迟,防止触发速率限制
except FloodWaitError as e:
print(f"Flood wait triggered. Sleeping for {e.seconds} seconds.")
await asyncio.sleep(e.seconds)
client.iter_participants(entity, limit=100)
只是生成了一个异步迭代器,而实际的 API 请求是在 async for participant in participants
中逐条触发的。因此,limit=100
并不会直接影响 async for
的请求行为,它只是限制了迭代器返回的参与者总数。
减少FloodWaitError的风险
可以增加一个参数batch_size
去控制请求的频率
async def sync_group_members(group_id: int):
entity = PeerChannel(group_id)
bot_group = await botGroup.get_or_none(group_id=group_id)
# 一次性获取所有参与者
participants = await client.get_participants(entity, limit=200)
# 分批处理用户,每批处理 10 个用户
batch_size = 10
try:
for i in range(0, len(participants), batch_size):
batch = participants[i:i + batch_size]
await process_batch(batch, bot_group)
await asyncio.sleep(random.uniform(5, 10)) # 随机等待 5-10 秒
except FloodWaitError as e:
await asyncio.sleep(e.seconds)
return False
async def process_batch(participants, bot_group):
for participant in participants:
业务逻辑
关于 limit
和 batch_size
的关系
-
limit
的作用:limit=100
表示你最多只会获取 100 个参与者。即使群组中有超过 100 个成员,iter_participants
也只会返回前 100 个。这个参数的作用是限制迭代器的返回数量,而不是控制 API 请求的频率。 -
batch_size
的作用:batch_size
是你自己定义的分批处理的大小。它决定了你在每次处理多少个参与者后等待一段时间。batch_size
与limit
是独立的,batch_size
不会影响limit
的行为。
为什么 limit
和 batch_size
看起来没有直接关系?
-
limit
控制的是总数:limit=100
表示你最多只会获取 100 个参与者。 -
batch_size
控制的是处理频率:batch_size=10
表示你每处理 10 个参与者后等待一段时间。
既然 limit
和 batch_size
是独立的,那就可以根据实际需求调整这两个参数:
-
limit
:如果你只关心前 100 个参与者,可以保留limit=100
。如果你需要获取更多参与者,可以增加limit
的值。 -
batch_size
:如果你希望减少 API 请求的频率,可以增加batch_size
的值,比如每批处理 20 个参与者。
QA:
如果要使用分页可以查看
https://czjdwy.xyz/index.php/archives/14/
需要查看字段解释请看:
https://czjdwy.xyz/index.php/archives/17/
本文系作者 @Mrjun 原创发布在懒猪儿Blog站点。未经许可,禁止转载。
全部评论 1
Mrjun
Google Chrome MacOS