爬取Telegram群组消息遇RuntimeError,求解决方案及优化方案
Telegram群组消息爬取错误解决与优化方案
错误原因
你遇到的RuntimeError: You must use "async with" if the event loop is running (i.e. you are inside an "async def")错误,是因为代码重复创建TelegramClient实例,且在同步客户端环境下误用嵌套with逻辑,引发事件循环冲突。
同步版本修复代码
优化同步客户端使用逻辑,避免重复初始化连接,同时替换已弃用的Pandas方法:
from telethon.sync import TelegramClient import datetime import pandas as pd import configparser config = configparser.ConfigParser() config.read("telethon.config") api_id = config["telethon_credentials"]["api_id"] api_hash = config["telethon_credentials"]["api_hash"] chats = ['cryptodubai7'] # 仅初始化一次客户端,复用连接 with TelegramClient('test', api_id, api_hash) as client: df = pd.DataFrame() for chat in chats: # 遍历目标群组消息 for message in client.iter_messages(chat, offset_date=datetime.date.today(), reverse=True): print(message) data = { "group": chat, "sender": message.sender_id, "text": message.text, "date": message.date } # 更简洁的DataFrame创建方式 temp_df = pd.DataFrame([data]) # 用concat替代已弃用的append,提升效率 df = pd.concat([df, temp_df], ignore_index=True) # 移除时区信息 df['date'] = df['date'].dt.tz_localize(None)
修复要点
- 只初始化一次TelegramClient,避免重复建立连接带来的资源浪费和冲突
- 替换
df.append为pd.concat,append在Pandas 2.0+版本已被弃用,concat效率更高 - 调整DataFrame初始化方式,直接传入数据列表更简洁
高效异步替代方案
若需爬取大量消息或多个群组,推荐使用Telethon异步API,效率更高且符合官方推荐用法:
import asyncio from telethon import TelegramClient import datetime import pandas as pd import configparser config = configparser.ConfigParser() config.read("telethon.config") api_id = config["telethon_credentials"]["api_id"] api_hash = config["telethon_credentials"]["api_hash"] chats = ['cryptodubai7'] async def fetch_group_messages(): async with TelegramClient('test', api_id, api_hash) as client: df = pd.DataFrame() for chat in chats: # 异步遍历消息,支持并发处理 async for message in client.iter_messages(chat, offset_date=datetime.date.today(), reverse=True): data = { "group": chat, "sender": message.sender_id, "text": message.text, "date": message.date } temp_df = pd.DataFrame([data]) df = pd.concat([df, temp_df], ignore_index=True) df['date'] = df['date'].dt.tz_localize(None) return df if __name__ == "__main__": # 运行异步任务 df = asyncio.run(fetch_group_messages()) print(df)
异步方案优势
- 异步IO可同时处理多个消息请求,爬取多群组或大数量消息时,效率远高于同步版本
- 完全符合Telethon设计逻辑,避免同步/异步混用导致的事件循环冲突问题
内容的提问来源于stack exchange,提问作者shaina ashraf
相关产品推荐
相关产品推荐

