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

解决Aiogram Bot调用TradingView截图函数时阻塞无响应问题

解决Aiogram机器人因TradingView截图阻塞的问题

问题描述

基于Aiogram框架开发的Telegram机器人,用于获取TradingView图表截图,但调用sellbot.send_chart()函数时耗时约12秒,导致机器人进入阻塞状态,无法响应其他用户请求。

机器人核心代码

from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
import sellbot
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from datetime import datetime


bot = Bot(token='54443480yi5vzrjMRivQ')
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)


class Form(StatesGroup):
    req = State()


@dp.message_handler(commands=['get'])
async def get(message):
    await Form.req.set()
    await message.answer(f'\U0001F916 request format:\nrialto\nticker\ntimeframe (minutes)')


@dp.message_handler(state=Form.req)
async def process_name(message: types.Message, state: FSMContext):
    await state.finish()
    splitmsg = message.text.split('\n')
    rialto, symbol, timeframe = splitmsg
    ticker = f'{rialto}:{symbol}'
    url = sellbot.send_chart(ticker, timeframe) # 阻塞点
    await message.answer_photo(url)


executor.start_polling(dp) 

sellbot模块阻塞代码

def screenshot(driver, ticker, timeframe):
    chart_url = config.urls["tvchart"] + ('?symbol=' + ticker) if ticker != 'NONE' else ''
    driver.get(chart_url)
    time.sleep(1)
    ActionChains(driver, duration=1).send_keys(timeframe).send_keys(Keys.ENTER).perform()
    ActionChains(driver).key_down(Keys.ALT).key_down('s').key_up(
        Keys.ALT).perform()
    time.sleep(2.5)
    clipboard = Tk().clipboard_get()
    return clipboard

def send_chart(ticker, timeframe):
    start_time = datetime.now()
    driver = setup()
    driver.get("https://www.tradingview.com")
    driver.add_cookie('...')
    screenshot_preurl = screenshot(driver, ticker, timeframe)
    return screenshot_url

解决方案

问题根源是同步阻塞函数sellbot.send_chart()占用了asyncio事件循环,导致机器人无法处理其他请求。核心解决思路是将同步代码放到线程池/进程池中异步执行,不阻塞主事件循环。

1. 用loop.run_in_executor异步执行同步函数

修改机器人中调用send_chart的逻辑,利用asyncio的线程池执行同步代码:

import asyncio  # 新增导入

@dp.message_handler(state=Form.req)
async def process_name(message: types.Message, state: FSMContext):
    await state.finish()
    splitmsg = message.text.split('\n')
    rialto, symbol, timeframe = splitmsg
    ticker = f'{rialto}:{symbol}'
    
    # 获取当前事件循环,在线程池中执行同步函数
    loop = asyncio.get_event_loop()
    url = await loop.run_in_executor(None, sellbot.send_chart, ticker, timeframe)
    
    await message.answer_photo(url)

2. 优化sellbot中的硬等待(可选)

screenshot函数中的time.sleep()是固定时长等待,可替换为Selenium显式等待,根据页面实际状态触发后续操作,减少不必要的耗时:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

def screenshot(driver, ticker, timeframe):
    chart_url = config.urls["tvchart"] + ('?symbol=' + ticker) if ticker != 'NONE' else ''
    driver.get(chart_url)
    # 等待图表画布加载完成,替代time.sleep(1)
    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.TAG_NAME, "canvas")))
    
    ActionChains(driver, duration=1).send_keys(timeframe).send_keys(Keys.ENTER).perform()
    ActionChains(driver).key_down(Keys.ALT).key_down('s').key_up(Keys.ALT).perform()
    
    # 等待剪贴板获取到截图URL,替代time.sleep(2.5)
    WebDriverWait(driver, 5).until(lambda d: Tk().clipboard_get() != '')
    clipboard = Tk().clipboard_get()
    return clipboard

3. 复用Selenium Driver(可选)

当前send_chart每次调用都重新初始化浏览器driver,这是主要耗时点之一。可以全局复用单个driver,避免重复启动浏览器:

# 在sellbot模块全局初始化driver
driver = None

def init_driver():
    global driver
    if not driver:
        driver = setup()
        driver.get("https://www.tradingview.com")
        driver.add_cookie('...')

def send_chart(ticker, timeframe):
    init_driver()
    screenshot_preurl = screenshot(driver, ticker, timeframe)
    return screenshot_url

注意需添加异常处理逻辑,当driver崩溃时自动重新初始化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:16:33