怎样在 PyScript 中正确显示天气预报数据

作者:袖梨 2026-07-01

本文详解 pyscript 项目中调用 yandex 天气 api 时页面无输出的问题根源,并提供使用 display() 替代 print()、修复异步请求与 json 解析错误的完整解决方案。

本文详解 pyscript 项目中调用 yandex 天气 api 时页面无输出的问题根源,并提供使用 display() 替代 print()、修复异步请求与 json 解析错误的完整解决方案。

在 PyScript 中,print() 函数的行为已发生重要变化:自版本 2023.11.1 起,print() 默认仅输出到浏览器开发者控制台(Console),不会渲染到网页 DOM 中。这正是您页面为空的根本原因——尽管请求成功、逻辑无报错,但结果未被展示。

此外,原代码中还存在两处关键错误:

  1. 重复解析响应:response.json() 被调用了两次(一次赋值给 response_dict,一次直接用于 data),而 pyodide.fetch().json() 返回的是 Promise,需 await;
  2. 未等待异步执行完成:asyncio.ensure_future() 启动协程后立即返回,PyScript 主线程可能在渲染前就结束了,导致 display() 未及时触发。

以下是修正后的完整可运行示例(兼容 PyScript ≥ 2024.1.1):

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <title>莫斯科天气预报</title>    <script defer src="https://pyscript.net/releases/2024.1.1/pyscript.js"></script>    <link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/pyscript.css"/></head><body>    <div id="weather-output"></div>    <py-script>        import pyodide        import asyncio        API_KEY = '8e4cf478-53b6-45bc-8597-9946db9f1fd5'        url = 'https://api.weather.yandex.ru/v2/forecast'        params = {            'lat': 55.753215,            'lon': 37.622504,            'lang': 'ru_RU'        }        headers = {            'X-Yandex-API-Key': API_KEY        }        async def get_weather():            try:                # 正确发起带参数和头信息的 GET 请求                response = await pyodide.http.pyfetch(                    url,                     method="GET",                     headers=headers,                     params=params                )                data = await response.json()  # ✅ 唯一且正确的 await 解析                fact = data.get('fact', {})                temperature = fact.get('temp', '未知')                condition = fact.get('condition', '未知')                # ✅ 使用 display() 将内容输出到页面(自动追加到 <py-script> 标签位置)                # 若需指定容器,可传入 target 参数(如 target="weather-output")                display(f"?️ 莫斯科实时天气:{temperature}°C,{condition}")            except Exception as e:                display(f"❌ 获取天气失败:{e}")        # ✅ 使用 asyncio.create_task() 或直接 await(PyScript 支持顶层 await)        await get_weather()    </py-script></body></html>

关键改进说明

  • 使用 pyodide.http.pyfetch()(推荐)替代已弃用的 pyodide.fetch(),语法更清晰、错误处理更健壮;
  • display() 是 PyScript 官方提供的 DOM 输出函数,支持字符串、HTML 片段、甚至 Pandas DataFrame 等对象;
  • 添加 try...except 捕获网络或解析异常,提升健壮性;
  • 移除冗余 asyncio.ensure_future(),改用 await get_weather() —— PyScript 2023.12+ 支持顶层 await,确保执行完成后再继续;
  • 显式指定 target 参数(如 display(..., target="weather-output"))可将内容精准插入指定 HTML 元素。

⚠️ 注意事项

  • Yandex 天气 API 需要有效 API Key 且可能限制免费调用量,请确认 Key 未过期、配额充足;
  • 浏览器 CORS 策略可能拦截跨域请求 —— Yandex API 支持前端直连,但若遇 CORS error,请检查响应头是否包含 Access-Control-Allow-Origin: *;
  • PyScript 加载期间页面可能短暂空白,建议添加加载提示(如 <div>Loading...</div>)提升用户体验。

通过以上调整,您的天气预报将清晰、稳定地呈现在网页上,而非仅藏于控制台。

相关文章

精彩推荐