如何解决使用 Telegram API 时出现的“telegram.error.BadRequest:网页内容类型错误”错误?

问题描述 投票:0回答:1

我编写了一个脚本来对 Telegram 机器人进行编程,以根据用户的选择将天气预报信息返回给用户。有 3 个选项: (1) 2 小时预报; (2)24小时预报; (3) 4 天预测。该脚本驻留在 pythonanywhere 服务器上。

该脚本将调用天气预报网站的 API 来获取信息。

然后将信息合并到 pandas 数据框中,然后将其保存为 png 文件。

目的是让 Telegram 机器人使用

update.message.reply_photo(response)
将 png 文件发送回用户。
response
是一个 HTTPS 链接,可打开保存在 pythonanywhere 服务器上的图像。

运行脚本后,我遇到了

telegram.error.BadRequest: Wrong type of the web page content
错误。我对此感到困惑,因为 Telegram API 文档指出 URL 被接受作为参数。

我已经在下面包含了我的脚本和回溯消息。我故意屏蔽了我的 API 令牌和用户名。这被替换为

<purposely_masked_out>

仅供参考:我已经在本地计算机上运行了该脚本并且运行良好。 pythonanywhere 上托管的脚本(给我错误的脚本)与本地计算机上的脚本之间的区别在于传递给

update.message.reply_photo(response)
的参数。区别如下:

*本地计算机:脚本将 png 文件保存在我的桌面上,响应指的是 png 的文件名。

Pythonanywhere:脚本将 png 文件保存在我的 pythonanywhere 文件夹中,响应引用了 png 的 URL。我不确定是否是因为该文件需要登录 pythonanywhere 才能访问它。*

请帮忙。

**我的脚本:**

import requests
import pandas as pd
import json
from typing import Final
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
import df2img

BOT_TOKEN: Final = <purposely_masked_out>
BOT_USERNAME: Final = <purposely_masked_out>

async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text('Hi! You can check the SG weather by typing \'2 hours\', \'24 hours\' or \'4 days\'')

def handle_response(text: str) -> str:
    # 2 hours weather data extraction
    if '2 hours' in text:
        two_r = requests.get('https://api.data.gov.sg/v1/environment/2-hour-weather-forecast').json()
        two_df = pd.DataFrame(columns=['area', 'forecast'])

        for i in range(len(two_r['items'][0]['forecasts'])):
            two_df.loc[i] = [(two_r['items'][0]['forecasts'][i]['area']),
                             (two_r['items'][0]['forecasts'][i]['forecast'])]

        fig = df2img.plot_dataframe(two_df)
        df2img.save_dataframe(fig=fig, filename='SG 2 hour weather.png')
        return 'https://www.pythonanywhere.com/user/<purposely_masked_out>/files/home/<purposely_masked_out>/SG 2 hour weather.png'

    # 24 hours weather data extraction
    elif '24 hours' in text:
        two_four_r = requests.get('https://api.data.gov.sg/v1/environment/24-hour-weather-forecast').json()

        # compiling the forecast data
        forecast = list(two_four_r['items'][0]['periods'][0]['regions'].values())
        temp_list = []

        for i in range(1, 3):
            temp_list.extend(list(two_four_r['items'][0]['periods'][i]['regions'].values()))

        for x in range(len(temp_list)):
            forecast.append(temp_list[x])

        # compiling the region data
        region = list(two_four_r['items'][0]['periods'][0]['regions'].keys()) * 3

        # compiling the period data
        period = ['first 8 hours'] * 5 + ['next 8 hours'] * 5 + ['subsequent 8 hours'] * 5

        # compiling all 3 above together
        d = {}
        d['forecast'] = forecast
        d['region'] = region
        d['period'] = period

        # convert into a dataframe for extraction
        two_four_df = pd.DataFrame(d)
        two_four_df = two_four_df[['period', 'region', 'forecast']]

        fig = df2img.plot_dataframe(two_four_df)
        df2img.save_dataframe(fig=fig, filename='SG 24 hour weather.png')
        return 'https://www.pythonanywhere.com/user/<purposely_masked_out>/files/home/<purposely_masked_out>/SG 24 hour weather.png'

    # 4 days weather data extraction
    elif '4 days' in text:
        four_day_r = requests.get('https://api.data.gov.sg/v1/environment/4-day-weather-forecast').json()
        four_day_df = pd.DataFrame(columns=['forecast'])

        for i in range(4):
            four_day_df.loc[i] = [four_day_r['items'][0]['forecasts'][i]['forecast']]

        fig = df2img.plot_dataframe(four_day_df)
        df2img.save_dataframe(fig=fig, filename='SG 4 days weather.png')
        return 'https://www.pythonanywhere.com/user/<purposely_masked_out>/files/home/<purposely_masked_out>/SG 4 day weather.png'

    else:
        return 'I don\'t understand. Please select between \'2 hours\', \'24 hours\' or \'4 days\' and type them properly without spacing'

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text: str = update.message.text
    response = handle_response(text)

    await update.message.reply_photo(response)

if __name__ == '__main__':
    print('Starting bot...')
    app = Application.builder().token(BOT_TOKEN).build()

    app.add_handler(CommandHandler('start', start_command))
    app.add_handler(MessageHandler(filters.TEXT, handle_message))

    print('Polling...')
    app.run_polling(poll_interval=3)

追溯消息:

No error handlers are registered, logging exception.
Traceback (most recent call last):
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/ext/_application.py", line 1184, in process_update
    await coroutine
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/ext/_basehandler.py", line 141, in handle_update
    return await self.callback(update, context)
  File "/home/<purposely_masked_out>/sg-weather-telegram-bot.py", line 89, in handle_message
    await update.message.reply_photo(response)
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_message.py", line 1391, in reply_photo
    return await self.get_bot().send_photo(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/ext/_extbot.py", line 2655, in send_photo
    return await super().send_photo(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_bot.py", line 394, in decorator
    result = await func(self, *args, **kwargs)  # skipcq: PYL-E1102
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_bot.py", line 1055, in send_photo
    return await self._send_message(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/ext/_extbot.py", line 517, in _send_message
    result = await super()._send_message(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_bot.py", line 572, in _send_message
    result = await self._post(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_bot.py", line 482, in _post
    return await self._do_post(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/ext/_extbot.py", line 335, in _do_post
    return await super()._do_post(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/_bot.py", line 510, in _do_post
    return await request.post(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/request/_baserequest.py", line 168, in post
    result = await self._request_wrapper(
  File "/home/<purposely_masked_out>/.local/lib/python3.10/site-packages/telegram/request/_baserequest.py", line 325, in _request_wrapper
    raise BadRequest(message)
telegram.error.BadRequest: Wrong type of the web page content
python telegram-bot python-telegram-bot pythonanywhere
1个回答
0
投票

我不确定是否是因为该文件需要登录 pythonanywhere 访问它

确实如此——在 PythonAnywhere 上,像

https://www.pythonanywhere.com/user/username/files/...
这样的 url 只能由登录用户
username
通过浏览器访问。如果您想以编程方式共享文件,您需要相应地提供它们。

© www.soinside.com 2019 - 2024. All rights reserved.