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

PythonAnywhere免费账户能否调用外部HTTPS API?请求被拒排查

问题:PythonAnywhere免费账户调用外部API失败排查与解决思路

问题背景

正在开发一款服务于关联卡牌游戏的Telegram机器人,参考PythonAnywhere教程结合ChatGPT输出编写代码。机器人可正常启动,但调用www.relationalgames.com获取卡牌数据时出现连接拒绝错误。

错误信息

File "/usr/local/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.relationalgames.com', port=443): Max retries exceeded with url: /cards?deck=Papo%20a%20Papo (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f46da0873a0>: Failed to establish a new connection: [Errno 111] Connection refused'))

当前代码

import telepot
import json
import random
import urllib3
import time

# You can leave this bit out if you're using a paid PythonAnywhere account
proxy_url = "http://proxy.server:3128"
telepot.api._pools = {
    'default': urllib3.ProxyManager(proxy_url=proxy_url, num_pools=3, maxsize=10, retries=False, timeout=30),
}
telepot.api._onetime_pool_spec = (urllib3.ProxyManager, dict(proxy_url=proxy_url, num_pools=1, maxsize=1, retries=False, timeout=30))
# end of the stuff that's only needed for free accounts

http = urllib3.PoolManager(timeout=60)

def handle(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)
    if content_type == 'text':
        if msg['text'] == '/start':
            bot.sendMessage(chat_id, "Enter the name of a deck:")
        else:
            #try:
                deck_name = msg['text']
                response = http.request('GET', f'https://www.relationalgames.com/cards?deck={deck_name}') # requests.get(f'https://www.relationalgames.com/cards?deck={deck_name}')
                print(response)
                playable_deck = json.loads(response.text)
                random.shuffle(playable_deck)

                while len(playable_deck) > 0:
                    card = playable_deck.pop()
                    if 'url' in card:
                        bot.sendMessage(chat_id, card['url'])
                    else:
                        bot.sendMessage(chat_id, card['cardText'])

                    if len(playable_deck) == 0:
                        bot.sendMessage(chat_id, "Do you want to restart the game? (yes or no)")
                        break

                    bot.sendMessage(chat_id, "Press any key for next card")
                    bot.getUpdates()
            #except:
             #   bot.sendMessage(chat_id, "Error processing your request")

TOKEN = 'My Token'
bot = telepot.Bot(TOKEN)
bot.message_loop(handle)

print ('Listening ...')

# Keep the program running.
while 1:
    time.sleep(10)

疑问与需求

需明确错误原因是PythonAnywhere免费账户限制,还是代码问题,并获取解决思路。


解决思路分析

1. 核心原因:代理配置不完整

PythonAnywhere免费账户对外发起所有HTTP/HTTPS请求必须使用官方指定代理(http://proxy.server:3128)。当前代码仅给Telepot库配置了代理,但用于请求卡牌网站的http = urllib3.PoolManager(timeout=60)未使用代理,导致连接被拒绝。

2. 代码修正步骤

  • 替换请求管理器为代理版本:
    把原有的http = urllib3.PoolManager(timeout=60)替换为:
    http = urllib3.ProxyManager(proxy_url=proxy_url, timeout=60)
    
  • 恢复异常捕获逻辑:取消try-except块的注释,避免程序崩溃,同时给用户返回错误提示。
  • 修复消息处理逻辑:bot.getUpdates()与message_loop冲突,会导致重复处理消息,建议改为基于状态的等待逻辑(比如用变量记录用户当前处于“等待下一张卡牌”的状态)。
  • URL编码优化:直接拼接deck_name可能导致编码错误,需对参数进行URL编码:
    from urllib.parse import quote
    encoded_deck_name = quote(deck_name)
    response = http.request('GET', f'https://www.relationalgames.com/cards?deck={encoded_deck_name}')
    

3. 验证步骤

在PythonAnywhere控制台执行以下命令,测试代理是否能正常访问目标网站:

curl -x http://proxy.server:3128 https://www.relationalgames.com/cards?deck=Papo

若能返回数据,说明代理配置有效;若仍失败,可能是目标网站屏蔽了PythonAnywhere的代理IP,或网站本身不可用。

4. 额外检查点

确认目标API路径是否正确:用户提供的示例URL是/cards/deck?Papo,但代码中使用的是/cards?deck={deck_name},需核对官方API文档确认正确路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:23:20