我正在尝试创建一个可以发送网页屏幕截图的电报机器人。
我使用 python-telegram-bot 来处理电报交互,并使用 python-playwright 来获取页面的屏幕截图。我的代码的问题是我在 Playwright 中遇到以下错误:
greenlet.error: cannot switch to a different thread
发生这种情况是因为我在调用电报命令时执行的函数之外声明了
browser = p.chromium.launch(headless=True, args=args)
。问题是,每次调用 telegram 命令时启动浏览器都会使我的代码速度减慢约 3 秒。我如何在全球范围内声明browser
?还可能吗?
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ParseMode
from telegram.ext import Updater, CommandHandler, ChatMemberHandler, CallbackQueryHandler
from telegram.error import Unauthorized, BadRequest
from playwright.sync_api import sync_playwright
args = [
"--no-sandbox",
"--disable-setuid-sandbox",
"--use-gl=egl",
]
p = sync_playwright().start()
browser = p.chromium.launch(headless=True, args=args)
def start(update, context):
page = browser.new_page()
page.goto("https://google.com")
page.screenshot(path="example.png")
page.close()
context.bot.send_photo(chat_id=update.effective_chat.id, photo=open("example.png", "rb"))
updater = Updater('2116084940:AAGxaA0wCwlg619UNstMeKzbuQVBoU-QCKA', use_context=True, workers=124)
updater.dispatcher.add_handler(CommandHandler('start', start, run_async=True))
updater.start_polling()
updater.idle()
我已经研究过了,并且我对你的代码做了很多更改,
我已经制作了一个机器人来尝试,直到成功完成为止。
我已将代码更改为async代码。
这是最后一个代码:
import telegram
from telegram import Update
from telegram.ext import MessageHandler, CommandHandler, Application, ContextTypes, filters
from playwright.async_api import async_playwright
args = [
"--no-sandbox",
"--disable-setuid-sandbox",
"--use-gl=egl",
]
# Replace 'YOUR_API_TOKEN' with the API token you received from BotFather.
API_TOKEN = 'yours'
async def download_screan_shot(link="www.google.com", id_of_chat=None, update_to_use_it_to_send_the_file=None):
file_name =f"{id_of_chat}_example.png"
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto(link)
await page.screenshot(path=file_name)
await browser.close()
await update_to_use_it_to_send_the_file.message.reply_photo(file_name)
async def messages(update, context):
the_gotten_message = update.message.text
if "www" in the_gotten_message:
await download_screan_shot(link=the_gotten_message, id_of_chat=update.message.from_user.id, update_to_use_it_to_send_the_file=update)
else:
await update.message.reply_text(update.message.text)
app = Application.builder().token(API_TOKEN).build()
app.add_handler(MessageHandler(filters.TEXT,messages))
app.run_polling()
我希望它对你有用。