You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Telethon与asyncio的Python脚本无法终止,无法生成CSV文件

问题排查与修复方案

核心原因

你的脚本持续运行无法生成CSV,是因为client.iter_messages默认会从最新消息开始,无限制遍历所有历史消息——哪怕已经处理完start_date之前的内容,它还会继续请求更早的消息,导致循环永远无法结束,自然执行不到生成CSV的代码段。

具体修复步骤

1. 添加遍历终止条件

由于iter_messages返回的消息是倒序排列(最新的在前),一旦遇到早于start_date的消息,直接跳出循环即可,后续消息肯定都不符合时间范围:

async for message in client.iter_messages("https://t.me/" + channel_username):
    msg_date = pd.Timestamp(message.date)
    # 一旦消息早于起始时间,直接终止遍历
    if msg_date < start_date:
        break
    if start_date <= msg_date <= end_date:
        # 剩余逻辑不变

2. 优化日期比较逻辑

不用转成timestamp,直接用pd.Timestamp对象比较,代码更简洁高效:

msg_date = pd.Timestamp(message.date)
if start_date <= msg_date <= end_date:
    # 处理符合条件的消息

3. 优化关键词匹配效率

原代码的嵌套循环顺序会导致重复检查,提前把关键词转成集合,匹配速度更快:

# 提前转成集合
keywords_set = set(keywords)
# 匹配逻辑优化
any(word in keywords_set for word in words_in_msg)

4. 规范TelegramClient导入

异步场景下建议使用异步版导入,替代from telethon.sync import TelegramClient:

from telethon import TelegramClient

修复后的完整代码

import asyncio
import nest_asyncio
from telethon import TelegramClient
import pandas as pd

username = "MY-USERNAME"   # 你的Telegram用户名
api_id = MY-API-ID   # 你的API ID
api_hash = "MY-API-HASH"   # 你的API Hash
phone = "MY-PHONE-NO"  # 带区号的手机号
channel_username = "clickhouse_en"  # 目标频道用户名
start_date_value = "2023-07-01 00:00:00"  # UTC起始时间
end_date_value = "2023-07-25 23:59:59"    # UTC结束时间
keywords_value = [] # 关键词列表,如["data", "report"]

# 应用nest_asyncio适配Jupyter环境
nest_asyncio.apply()  

async def main(start_date=None, end_date=None, keywords=None):
    # 转换时间格式
    start_date = pd.Timestamp(start_date)
    end_date = pd.Timestamp(end_date)

    # 处理关键词,转小写并转为集合提升匹配效率
    keywords = [kw.lower() for kw in keywords]
    keywords_set = set(keywords)
    
    data = [] 
    async with TelegramClient(username, api_id, api_hash) as client:
        async for message in client.iter_messages("https://t.me/" + channel_username):
            msg_date = pd.Timestamp(message.date)
            
            # 超出起始时间范围,直接终止遍历
            if msg_date < start_date:
                break
                
            # 检查是否在目标时间范围内
            if start_date <= msg_date <= end_date:
                msg_text_lower = str(message.text).lower()
                words_in_msg = msg_text_lower.split()
                # 无关键词时直接保留,或关键词匹配成功时保留
                if not keywords or any(word in keywords_set for word in words_in_msg):
                    print(msg_date, message.text, message.sender_id) 
                    data.append([msg_date, message.text, message.sender_id])

    # 生成DataFrame并导出CSV
    df = pd.DataFrame(data, columns=["message_date", "message_text", "sender_id"])
    df.to_csv('telegram_messages.csv', encoding='utf-8', index=False)

# 运行异步函数
loop = asyncio.get_event_loop()
loop.run_until_complete(main(start_date=start_date_value, end_date=end_date_value, keywords=keywords_value))

额外说明

  • 导出CSV时添加index=False可以避免生成多余的索引列
  • 如果频道消息量极大,可考虑给iter_messages添加limit参数限制单次请求的消息数量,避免内存占用过高

内容的提问来源于stack exchange,提问作者Leockl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:05:03