Telegram用户数据检索结果波动问题排查与Python+API解决方案咨询
问题:Telegram API拉取频道/群组成员数量波动异常
使用Python调用Telegram API拉取同一频道/群组的用户信息时,返回结果波动极大:有时能获取100名成员中的50名,有时仅能拿到3名及以下成员,需要排查潜在原因并给出解决步骤。
潜在原因分析
- API限流机制触发:Telegram对API请求频率有严格限制,短时间内多次请求会被限流,导致返回不完整数据或空结果
- 搜索逻辑存在缺陷:代码按单个字母遍历搜索,且遇到空结果就直接
break终止循环,会跳过后续字母对应的成员 - 成员隐私设置限制:部分用户隐藏了用户名或开启隐私保护,API无法返回这类用户的信息
- offset参数未迭代更新:代码中
offset始终设为0,每次请求只拉取前limit条数据,无法分页获取全部成员 - hash参数设置错误:
GetParticipantsRequest的hash参数硬设为0,不符合API要求,可能导致请求异常
解决步骤
- 添加限流处理:在每次请求后添加间隔(如
await asyncio.sleep(1)),捕获限流相关异常并实现重试逻辑 - 修复搜索循环逻辑:移除
if not participants.users: break语句,确保遍历完所有字母;或改用ChannelParticipantsAll直接拉取全部成员,避免按字母搜索的局限性 - 正确分页获取数据:每次请求后更新
offset为offset + len(participants.users),直到返回的participants.users为空,确保遍历所有分页 - 正确计算hash参数:使用Telethon内置的哈希计算方式,不要硬设为0(Telethon通常会自动处理,可省略该参数)
- 处理隐私用户边界情况:判断
user.username是否存在后再进行正则匹配,避免索引错误,例如:if user.username: first_char = re.findall(r"\b[a-zA-Z]", user.username)[0].lower() if first_char == key: # 处理用户数据
问题复现代码
# Initialize a flag to control user data retrieval user_data_flag = 0 # Set the maximum number of participants to retrieve in each request limit = 100 # Initialize the offset (starting point for retrieval) offset = 0 # Create an empty list to store all retrieved participants all_participants = [] # Check if user data retrieval is enabled if user_data_flag == 0: # Define a list of query keys (letters 'a' to 'z') to search for participants queryKey = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] # Iterate through each query key for key in queryKey: # Print the current query key being processed print(f"The Key is {key}\n") # Send a request to the Telegram API to retrieve participants whose usernames start with the current key participants = await client(GetParticipantsRequest( my_channel, ChannelParticipantsSearch(key), offset, limit, hash=0 )) # Check if there are no participants returned if not participants.users: break # Iterate through each user in the returned participants for user in participants.users: try: # Check if the first letter of the username (converted to lowercase) matches the current key if re.findall(r"\b[a-zA-Z]", user.username)[0].lower() == key: # Print the user's information print("USER ---->", user, "\n") # Append the user's information to the list of all participants all_participants.append(user) # Reset the unused variable 'c' to 0 c = 0
内容的提问来源于stack exchange,提问作者pythonteam
相关产品推荐
相关产品推荐

