python - Telethon Python asyncio TypeError:“协程”对象不可调用
问题描述
您需要获取有关频道、聊天、群组的信息。由于每个账号都有接收信息的限制,所以我会使用几个账号。我正在尝试获取信息,但出现错误:
Traceback (most recent call last):
File "D:/Git/telegram/telegram_new.py", line 50, in parse_entity
channel=entity
TypeError: 'coroutine' object is not callable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:/Git/telegram/telegram_new.py", line 56, in parse_entity
id=entity
TypeError: 'coroutine' object is not callable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:/Git/telegram/telegram_new.py", line 60, in parse_entity
chat_id=entity
TypeError: 'coroutine' object is not callable
帮助修复错误
代码:
import logging
from telethon import TelegramClient,sync, utils, errors
from telethon.tl.types import PeerUser, PeerChat
from telethon import functions, types
import pandas as pd
import time
import re
import asyncio
from contextlib import suppress
import traceback
log = logging.getLogger(__name__)
format = '%(asctime)s %(levelname)s:%(message)s'
logging.basicConfig(format=format, level=logging.INFO)
api_id = "" #(my.telegram.org)
api_hash = ""
filename_excel = "project_for_export_no_formulas_31_10_18.xlsx"
filename_numbers = "number.txt"
queue_entity = asyncio.Queue()
numbers = []
count_thread = 8
def load_numbers(filename):
with open(filename, "r") as file:
content = file.read().split("\n")
for conten in content:
numbers.append(conten)
def load_excel(output_filename):
data = pd.read_excel(output_filename, 'Projects', dtype=str)
for item in data["Telegram link"]:
if item != "nan":
queue_entity.put_nowait(item)
async def create_client(number):
print(number)
client = TelegramClient(number, api_id, api_hash).start()
return client
async def parse_entity(entity, client_coroutine):
result = None
client = await client_coroutine
try:
result = client(functions.channels.GetFullChannelRequest(
channel=entity
))
print("Успешно")
except TypeError:
try:
result = client(functions.users.GetFullUserRequest(
id=entity
))
except TypeError:
result = client(functions.messages.GetFullChatRequest(
chat_id=entity
))
except errors.UsernameInvalidError:
print("Не найден пользователь, канал или чат")
except errors.InviteHashExpiredError:
print("Чата больше нет")
except errors.InviteHashInvalidError:
print("Ссылка приглашения не валидна")
except ValueError:
print("Невозможно получить entity. Для начала нужно вступить в группу или чат")
except errors.FloodWaitError:
print("Ожидание суток")
return result
async def crawl(future):
futures = []
numbers = await future
for client in asyncio.as_completed([create_client(number) for number in numbers]):
while queue_entity.qsize() > 0:
futures.append(asyncio.ensure_future(parse_entity(queue_entity.get_nowait(), client)))
if futures:
await asyncio.wait(futures)
async def start_main(root):
print(root)
loop = asyncio.get_event_loop()
initial_future = loop.create_future()
initial_future.set_result(root)
await crawl(initial_future)
if __name__ == '__main__':
start = time.time()
load_numbers(filename_numbers) #Загрузка телефонов
load_excel(filename_excel) #Загрузка Excel
loop = asyncio.get_event_loop()
# loop.set_debug(True)
try:
loop.run_until_complete(start_main(numbers))
except KeyboardInterrupt:
for task in asyncio.Task.all_tasks():
task.cancel()
with suppress(asyncio.CancelledError):
loop.run_until_complete(task)
finally:
loop.close()
log.info("Time work: %s", time.time() - start)
在我的区域论坛,没有人可以帮助我,所以我在这里写,因为英语社区更多,有人可以帮助
更新
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:/Git/telegram/telegram_new.py", line 54, in parse_entity
result = client(functions.users.GetFullUserRequest(id=entity))
TypeError: 'coroutine' object is not callable
更新 2
future: <Task finished coro=<parse_entity() done, defined at D:/Git/telegram/telegram_new.py:45> exception=RuntimeError('coroutine is being awaited already')>
更新 3
Traceback (most recent call last):
File "D:/Git/telegram/telegram_new.py", line 95, in <module>
loop.run_until_complete(start_main(numbers))
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 568, in run_until_complete
return future.result()
File "D:/Git/telegram/telegram_new.py", line 86, in start_main
await crawl(initial_future)
File "D:/Git/telegram/telegram_new.py", line 75, in crawl
for client in asyncio.as_completed([await create_client(number) for number in numbers]):
File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 505, in as_completed
todo = {ensure_future(f, loop=loop) for f in set(fs)}
File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 505, in <setcomp>
todo = {ensure_future(f, loop=loop) for f in set(fs)}
File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 588, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
2018-12-27 18:14:49,534 ERROR:Task was destroyed but it is pending!
task: <Task pending coro=<UpdateMethods._update_loop() running at C:\ProgramData\Anaconda3\lib\site-packages\telethon\client\updates.py:215> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001A379824108>()]>>
2018-12-27 18:14:49,534 ERROR:Task was destroyed but it is pending!
task: <Task pending coro=<MTProtoSender._send_loop() running at C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\mtprotosender.py:375> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001A379824138>()]>>
2018-12-27 18:14:49,534 ERROR:Task was destroyed but it is pending!
task: <Task pending coro=<MTProtoSender._recv_loop() running at C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\mtprotosender.py:413> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001A3798242B8>()]>>
Exception ignored in: <coroutine object MTProtoSender._recv_loop at 0x000001A37980A948>
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\mtprotosender.py", line 413, in _recv_loop
File "C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py", line 123, in recv
File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 672, in call_soon
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 461, in _check_closed
RuntimeError: Event loop is closed
2018-12-27 18:14:49,534 ERROR:Task was destroyed but it is pending!
task: <Task pending coro=<Connection._send_loop() running at C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py:135> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001A379824228>()]>>
2018-12-27 18:14:49,534 ERROR:Task was destroyed but it is pending!
task: <Task pending coro=<Connection._recv_loop() running at C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py:150> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001A379824288>()]>>
2018-12-27 18:14:49,535 ERROR:Unexpected exception in the send loop
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 159, in get
await getter
GeneratorExit
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py", line 135, in _send_loop
self._send(await self._send_queue.get())
File "C:\ProgramData\Anaconda3\lib\asyncio\queues.py", line 161, in get
getter.cancel() # Just in case getter is not done yet.
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 672, in call_soon
self._check_closed()
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 461, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <coroutine object Connection._send_loop at 0x000001A37980AA48>
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py", line 142, in _send_loop
File "C:\ProgramData\Anaconda3\lib\site-packages\telethon\network\connection\connection.py", line 94, in disconnect
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 672, in call_soon
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 461, in _check_closed
RuntimeError: Event loop is closed
解决方案
因为TelegramClient.start
它是一个异步函数,所以你必须这样await
做:
async def create_client(number):
return await TelegramClient(number, api_id, api_hash).start()
我对您的代码做了两个显着的更改:
create_client(number)
将调用包装在asyncio.as_completed
. 原因是它create_client(number)
返回一个协程对象,但是asyncio.as_completed
需要一个期货列表。这是as_completed
文档字符串:
as_completed(fs, *, loop=None, timeout=None) 返回一个迭代器,其值为协程。
When waiting for the yielded coroutines you'll get the results (or exceptions!) of the original Futures (or coroutines), in the order in which and as soon as they complete. This differs from PEP 3148; the proper way to use this is: for f in as_completed(fs): result = await f # The 'await' may raise. # Use result.
- 更改
loop.close()
为loop.stop()
. 否则循环将被关闭,当仍有正在运行的任务时我们将得到异常。
以下是我编辑您的代码以使其工作的方式:
import logging
from telethon import TelegramClient,sync, utils, errors
from telethon.tl.types import PeerUser, PeerChat
from telethon import functions, types
import pandas as pd
import time
import re
import asyncio
from contextlib import suppress
import traceback
log = logging.getLogger(__name__)
format = '%(asctime)s %(levelname)s:%(message)s'
logging.basicConfig(format=format, level=logging.INFO)
api_id = ""
api_hash = ""
filename_excel = "project_for_export_no_formulas_31_10_18.xlsx"
filename_numbers = "number.txt"
queue_entity = asyncio.Queue()
numbers = []
count_thread = 8
def load_numbers(filename):
with open(filename, "r") as file:
content = file.read().split("\n")
for conten in content:
numbers.append(conten)
def load_excel(output_filename):
data = pd.read_excel(output_filename, 'Projects', dtype=str)
for item in data["Telegram link"]:
if item != "nan":
queue_entity.put_nowait(item)
async def create_client(number):
return await TelegramClient(number, api_id, api_hash).start()
async def parse_entity(entity, client):
result = None
try:
result = client(functions.channels.GetFullChannelRequest(
channel=entity
))
print("Успешно")
except TypeError:
try:
result = client(functions.users.GetFullUserRequest(
id=entity
))
except TypeError:
result = client(functions.messages.GetFullChatRequest(
chat_id=entity
))
except errors.UsernameInvalidError:
print("Не найден пользователь, канал или чат")
except errors.InviteHashExpiredError:
print("Чата больше нет")
except errors.InviteHashInvalidError:
print("Ссылка приглашения не валидна")
except ValueError:
print("Невозможно получить entity. Для начала нужно вступить в группу или чат")
except errors.FloodWaitError:
print("Ожидание суток")
return result
async def crawl(future):
futures = []
numbers = await future
for f in asyncio.as_completed([asyncio.ensure_future(create_client(number)) for number in numbers]):
client = await f
while queue_entity.qsize() > 0:
futures.append(asyncio.ensure_future(parse_entity(queue_entity.get_nowait(), client)))
if futures:
await asyncio.wait(futures)
async def start_main(root):
loop = asyncio.get_event_loop()
initial_future = loop.create_future()
initial_future.set_result(root)
await crawl(initial_future)
if __name__ == '__main__':
start = time.time()
load_numbers(filename_numbers) #Загрузка телефонов
#load_excel(filename_excel) #Загрузка Excel
loop = asyncio.get_event_loop()
# loop.set_debug(True)
try:
loop.run_until_complete(start_main(numbers))
except KeyboardInterrupt:
for task in asyncio.Task.all_tasks():
task.cancel()
with suppress(asyncio.CancelledError):
loop.run_until_complete(task)
finally:
loop.stop()
log.info("Time work: %s", time.time() - start)
我希望它有所帮助。
推荐阅读
- ms-access - MS Access 365,使用 DLookup 在非组合框上查找信息
- haskell - 寻找一种更好的方法来编写一个将类型构造函数作为参数的函数
- android - 应用内购买验证:错误 401 权限不足
- javascript - Try to put space between items with splice function but when reload page crash (javascript)
- javascript - 联系表单脚本 Ajax 无法识别来自 Mail.php 的正确结果
- react-native - 运行 React Native 应用程序时出现“找不到变量:a”错误
- unity3d - 等轴测 3D Unity 项目中的 2D 精灵
- python - 如何在pygame rect框中获取条形码扫描仪输出
- java - 在 JQuery 中使用 ajax 方法 .get() 和 .post() 添加到购物车
- javascript - 使用数据表上的单击事件调用“组件函数”