8

我是 Telethon 和 python 的新手。我已经在 python3 中安装了 telethon,我想获取电报频道或组的所有成员。我在互联网上搜索了很多,发现下面的代码。而且我正在努力理解它。电报文档不足以做到这一点。有更好的解决方案吗?

from telethon import TelegramClient

from telethon.tl.functions.contacts import ResolveUsernameRequest
from telethon.tl.functions.channels import GetAdminLogRequest
from telethon.tl.functions.channels import GetParticipantsRequest

from telethon.tl.types import ChannelParticipantsRecent
from telethon.tl.types import InputChannel
from telethon.tl.types import ChannelAdminLogEventsFilter
from telethon.tl.types import InputUserSelf
from telethon.tl.types import InputUser
# These example values won't work. You must get your own api_id and
# api_hash from https://my.telegram.org, under API Development.
api_id = 12345
api_hash = '8710a45f0f81d383qwertyuiop'
phone_number = '+123456789'

client = TelegramClient(phone_number, api_id, api_hash)





client.session.report_errors = False
client.connect()

if not client.is_user_authorized():
    client.send_code_request(phone_number)
    client.sign_in(phone_number, input('Enter the code: '))

channel = client(ResolveUsernameRequest('channelusername')) # Your channel username

user = client(ResolveUsernameRequest('admin')) # Your channel admin username
admins = [InputUserSelf(), InputUser(user.users[0].id, user.users[0].access_hash)] # admins
admins = [] # No need admins for join and leave and invite filters

filter = None # All events
filter = ChannelAdminLogEventsFilter(True, False, False, False, True, True, True, True, True, True, True, True, True, True)
cont = 0
list = [0,100,200,300]
for num in list:
    result = client(GetParticipantsRequest(InputChannel(channel.chats[0].id, channel.chats[0].access_hash), filter, num, 100))
    for _user in result.users:
        print( str(_user.id) + ';' + str(_user.username) + ';' + str(_user.first_name) + ';' + str(_user.last_name) )
with open(''.join(['users/', str(_user.id)]), 'w') as f: f.write(str(_user.id))

但我收到了这个错误。我错过了什么?

Traceback (most recent call last):
  File "run.py", line 51, in <module>
    result = client(GetParticipantsRequest(InputChannel(channel.chats[0].id, channel.chats[0].access_hash), filter, num, 100))
TypeError: __init__() missing 1 required positional argument: 'hash'
4

6 回答 6

7

肖恩的回答不会有任何区别。

您的代码适用于较旧的 Telethon 版本。在新版本中,方法hash中添加了一个新参数GetParticipantsRequest。因此,您也需要hash作为参数传递。像这样添加hash=0

result = client(GetParticipantsRequest(InputChannel(channel.chats[0].id, channel.chats[0].access_hash), filter, num, 100, 0))

请注意,hash请求的不是通道哈希。这是一个根据你已经知道的参与者计算的特殊哈希,所以 Telegram 可以避免重新发送整个事情。您可以将其保留为 0。

是来自官方 Telethon wiki 的最新示例。

于 2017-12-20T06:25:30.323 回答
3

我认为您可以在新版本中使用此代码Telethon

from telethon import TelegramClient
from telethon.tl.functions.channels import GetParticipantsRequest
from telethon.tl.functions.channels import GetFullChannelRequest
from telethon.tl.types import ChannelParticipantsSearch

api_id = XXXXX
api_hash = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
phone_number = '+98XXXXXXXX'
################################################
channel_username = 'tehrandb'
################################################

client = TelegramClient('session_name',api_id,api_hash)

assert client.connect()
if not client.is_user_authorized():
    client.send_code_request(phone_number)
    me = client.sign_in(phone_number, input('Enter code: '))

# ---------------------------------------
offset = 0
limit = 200
my_filter = ChannelParticipantsSearch('')
all_participants = []
while_condition = True
# ---------------------------------------
channel = client(GetFullChannelRequest(channel_username))
while while_condition:
    participants = client(GetParticipantsRequest(channel=channel_username, filter=my_filter, offset=offset, limit=limit, hash=0))
    all_participants.extend(participants.users)
    offset += len(participants.users)
    if len(participants.users) < limit:
         while_condition = False

我用的是‍<code>Telethon V0.19,但之前的版本几乎一样

于 2018-05-17T09:48:59.597 回答
3
channel = client(ResolveUsernameRequest('channel_name'))
user_list = client.iter_participants(entity=channel)
for _user in user_list:
    print(_user)

或者

user_list = client.get_participants(entity=channel)
for _user in user_list:
    print(_user)

于 2020-09-15T11:55:01.693 回答
2

使用 Telethon 获取电报频道所有用户的简单方法。并确保您具有用于频道或组的有效权限(由 GetParticipantsRequest 引起)。

from telethon.tl.functions.contacts import ResolveUsernameRequest

channel = await client(ResolveUsernameRequest('channel_name'))
async for _user in client.iter_participants(entity=channel):
      print(_user)
于 2021-09-02T14:23:42.707 回答
1

你可以试试下面的代码,它有效,我测试过。但我确实有一个问题,因为 Telethon 库并没有增加所有用户,它只增加了 90% 的用户。我认为它以某种方式跳过了一些......不知道为什么。

from telethon.sync import TelegramClient
from telethon.tl.functions.messages import GetDialogsRequest
from telethon.tl.types import InputPeerEmpty
import csv

api_id = 123456
api_hash = 'YOUR_API_HASH'
phone = '+111111111111'
client = TelegramClient(phone, api_id, api_hash)

client.connect()
if not client.is_user_authorized():
    client.send_code_request(phone)
    client.sign_in(phone, input('Enter the code: '))


chats = []
last_date = None
chunk_size = 200
groups=[]
 
result = client(GetDialogsRequest(
             offset_date=last_date,
             offset_id=0,
             offset_peer=InputPeerEmpty(),
             limit=chunk_size,
             hash = 0
         ))
chats.extend(result.chats)

for chat in chats:
    try:
        if chat.megagroup== True:
            groups.append(chat)
    except:
        continue

print('Choose a group to scrape members from:')
i=0
for g in groups:
    print(str(i) + '- ' + g.title)
    i+=1

g_index = input("Enter a Number: ")
target_group=groups[int(g_index)]

print('Fetching Members...')
all_participants = []
all_participants = client.get_participants(target_group, aggressive=True)

print('Saving In file...')
with open("members.csv","w",encoding='UTF-8') as f:
    writer = csv.writer(f,delimiter=",",lineterminator="\n")
    writer.writerow(['username','user id', 'access hash','name','group', 'group id'])
    for user in all_participants:
        if user.username:
            username= user.username
        else:
            username= ""
        if user.first_name:
            first_name= user.first_name
        else:
            first_name= ""
        if user.last_name:
            last_name= user.last_name
        else:
            last_name= ""
        name= (first_name + ' ' + last_name).strip()
        writer.writerow([username,user.id,user.access_hash,name,target_group.title, target_group.id])      
print('Members scraped successfully.')
于 2021-06-19T13:56:08.200 回答
-1

使用client.invoke()而不是client().

可以参考官方指南

于 2017-12-07T16:01:43.587 回答