恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

用Python请求NASA公开API:从数据采集到可视化实战

  • 首页
  • 资讯中心
  • /
  • 用Python请求NASA公开API:从数据采集到可视化实战

相关资讯

PSO-SVM参数优化实战:让SVM不再熬夜调参 2026/10/12 21:40:22
数学建模30个常用算法Python实现与可控调用指南 2026/10/12 21:40:22
纯NumPy机器学习算法骨架:可调试、可插拔、可回溯 2026/10/12 21:40:22

最新资讯

朴素贝叶斯搞定豆瓣影评情感分类:从爬虫到模型评估全流程
开源一个心流舱付费空间番茄风水钟:用Cursor+Web打造专注时钟
OpenClaw昵称“小龙虾”AI Agent工具:把settings改到TaoToken的配置与验证
open-code-review:从规则前置到知识回流的代码审查机制设计
ESP32S3 Dev Module入门:Arduino IDE配置与实战指南
ComfyUI+AnimateDiff+ControlNet:让线稿变成稳定动画的AI工作流

今日推荐

Debian新手入门:从部署到日常操作的完整指南
MongoDB复制集扩缩容实战:从rs.add到选主事故复盘
条形码目标检测数据集实战:从YOLOv8训练到部署

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

用Python请求NASA公开API:从数据采集到可视化实战

发布时间:2026/10/12 21:45:22
用Python请求NASA公开API:从数据采集到可视化实战 1. 为什么我建议你从NASA公开API玩起我一直觉得搞数据分析的人如果没碰过NASA的公开API多少有点可惜。这不是客套话——在这些接口里你能找到近地天体轨道参数、火星探测器实时天气、每天更新的天文照片、甚至卫星拍摄的地球夜景数据。关键是它们全部免费不需要走复杂的审批流程只要注册个账号拿到密钥就能开始调。对于一个想练手Python爬虫、数据处理或可视化的人来说这几乎是质量最高、最能激发兴趣的练手场地。我最初接触这个项目是因为想做一个“今日天文图片自动推送”的小工具。原以为要到处找图片资源结果发现NASA的APOD每日天文图片接口直接把图片URL和说明文字打包好等着你取。后来顺着这个入口我把近地天体数据、火星天气、地球卫星影像这几个接口都研究了一遍发现它们的请求方式和返回结构差异不小作为Python学习的实战案例再合适不过。这篇文章会按照我实际踩过的路径从注册密钥、读懂文档、写出第一个请求到用pandas做数据处理、用matplotlib做可视化完整地走一遍。如果你正在学Python的requests、json、pandas这几个库又不想对着假数据练手这个方向会很对你胃口。2. 开发前的准备账号、密钥和请求规范2.1 注册账号与申请API KeyNASA的开放API平台汇集了几十个数据接口但统一的管理入口就一个。打开它的API门户用邮箱注册一个账号然后创建一个应用就能获得专属密钥。这个过程有个细节值得注意创建应用时需要填写应用描述随意填个类似“个人学习项目”就行但应用名称会影响到你对密钥的管理建议写清楚用途比如“near-earth-monitor”免得以后申请多个密钥时分不清哪个对应哪个。拿到密钥后你会在控制台看到类似这样格式的字符串abcde12345fghij67890klmnopqrstuvwxyz这个就是你的API Key。它本质上是服务端用来识别你身份和统计调用次数的凭证相当于你进入数据房间的工牌。很多新手会犯一个低级错误——把密钥直接写死在代码里然后传到公开仓库。NASA的接口本身是只读数据接口泄露密钥的风险虽然没有支付接口那么大但被恶意盗刷导致IP被限流的问题依旧会让你很难受。我个人的习惯是用环境变量或本地配置文件保存密钥代码里通过读取方式引入。2.2 接口寻址和请求限制NASA的API域名统一但各接口路径不同。我实际测试下来常用的几个入口如下接口用途基础路径说明每日天文图片https://api.nasa.gov/planetary/apod返回当天的天文图片及说明近地天体https://api.nasa.gov/neo/rest/v1/neo/browse小行星轨道数据列表火星天气https://api.nasa.gov/insight_weather/?api_keyDEMO_KEY洞察号火星车的气象数据地球卫星影像https://api.nasa.gov/planetary/earth/assets特定经纬度的Landsat影像所有接口都支持通过api_key参数做身份验证。请求频率方面标准密钥通常有每小时调用次数的限制具体的数字在文档里会写明。我个人的建议是给每个请求加上至少1秒的间隔多个接口循环采集时用time.sleep(1)控制节奏这样基本不会触发限流。如果你不做任何限制地开多线程猛抓很快会收到429状态码——那时候再回头改代码折腾的时间够你把数据抓好几遍了。2.3 读文档的正确姿势我发现很多初学者拿到接口文档后习惯先去看参数列表但正确顺序其实是先看示例响应。因为NASA的每个接口返回的JSON结构差异很大有的数据嵌得特别深不先搞清楚返回结构就盲目写解析代码很容易在复杂的嵌套里迷失。以近地天体接口的返回为例最外层是element_count和near_earth_objects后者是一个以日期为键的字典每个日期下又有多个小行星对象小行星对象里面还有estimated_diameter、close_approach_data这种继续嵌套的结构。如果你是第一次处理这种多层JSON建议先把响应保存成文件用文本编辑器观察层级关系再动手写解析逻辑。这样比边写代码边猜字段高效得多至少能少掉一半调试时间。3. 从第一个请求到批量数据采集3.1 用requests发送GET请求不论目标接口是哪个用Python发起请求的底层逻辑都是相通的。以最简单的APOD接口为例直接上代码import requests API_KEY 你的密钥 url https://api.nasa.gov/planetary/apod params { api_key: API_KEY, date: 2023-10-01 } response requests.get(url, paramsparams) print(response.status_code) data response.json() print(data[title]) print(data[url])这里有个容易被忽略的细节用params参数传查询字符串比直接拼URL优雅得多尤其在值里包含特殊字符时requests会自动帮你做URL编码。比如日期参数里的横杠、时间参数里的冒号如果直接拼字符串很容易出问题而params方案从源头上规避了这个麻烦。response.json()会直接解析响应体中的JSON字符串把它转换成Python的字典。这一步背后依赖的是标准库中的json模块等价于先取response.text再用json.loads()解析。如果你需要处理的数据格式不只是JSON比如某些NASA接口支持csv格式输出那么就要改用response.text自己处理。我之前试过Earth数据接口的返回比较特别所以才会想先解析成Python对象再决定是否用pandas处理。3.2 异常处理和状态码检查直接裸写requests.get()在公司级项目里是不可能出现的因为网络状况、接口波动、参数错误都会导致请求异常。一个完整的请求函数应该包含如下逻辑import requests import time def fetch_nasa_data(url, params, retries3): for attempt in range(retries): try: response requests.get(url, paramsparams, timeout10) if response.status_code 200: return response.json() elif response.status_code 429: wait_time 2 ** attempt time.sleep(wait_time) else: response.raise_for_status() except requests.exceptions.Timeout: print(f请求超时第{attempt 1}次重试) time.sleep(2) except requests.exceptions.RequestException as e: print(f请求失败{e}) break return None这段代码里包含了几层考虑timeout10防止请求卡死429状态码时做指数退避等待给限流留出恢复时间每次重试间隔递增。实际使用中偶尔会遇到某个接口突然返回500这种情况多半是对方服务端临时问题等几秒重试就好。这套逻辑并不复杂但每次写请求都带上它能让你的采集程序稳定好几个档次。3.3 批量获取近地天体数据理解了单个请求的写法后批量采集就是一个循环加延时的问题。不过这个接口的设计有个规律要注意https://api.nasa.gov/neo/rest/v1/neo/browse只返回当前页的20条记录全部数据需要通过分页来拉取。响应里提供了links.next字段直接用这个URL继续请求就行。我做近地天体数据采集时会按日期范围循环请求。示例代码如下import requests import json import time API_KEY 你的密钥 base_url https://api.nasa.gov/neo/rest/v1/neo/browse params {api_key: API_KEY} all_asteroids [] page 0 while True: response requests.get(base_url, paramsparams, timeout15) if response.status_code ! 200: print(f请求失败状态码{response.status_code}) break data response.json() asteroids data.get(near_earth_objects, []) all_asteroids.extend(asteroids) print(f第{page 1}页获取到{len(asteroids)}条记录) next_link data.get(links, {}).get(next) if not next_link: break base_url next_link page 1 time.sleep(1) print(f共获取{len(all_asteroids)}条小行星数据)跑完这个循环你手上就有了上千条小行星的轨道数据。这里能明显感受到python列表的extend方法有多方便——它会把新获取的数据追加到列表末尾不会造成数据覆盖。之后再把这个列表整体转换成pandas的DataFrame分析工作就正式开始了。4. 数据处理把JSON变成能分析的结构4.1 用pandas清洗嵌套JSON从API拿到的JSON结构嵌套严重直接塞进DataFrame会得到一堆字典对象无法直接用于数值统计。处理思路是把需要的字段逐个抽出来建立一个新的“平坦化”结构。以近地天体数据的清洗为例我通常会提取以下字段import pandas as pd import json def flatten_asteroid(asteroid): return { name: asteroid.get(name), absolute_magnitude: asteroid.get(absolute_magnitude_h), diameter_min_km: asteroid.get(estimated_diameter, {}). get(kilometers, {}).get(estimated_diameter_min), diameter_max_km: asteroid.get(estimated_diameter, {}). get(kilometers, {}).get(estimated_diameter_max), is_potentially_hazardous: asteroid.get( is_potentially_hazardous_asteroid), close_approach_date: asteroid.get(close_approach_data, [{}])[0]. get(close_approach_date), relative_velocity_kph: asteroid.get(close_approach_data, [{}])[0]. get(relative_velocity, {}). get(kilometers_per_hour) } flat_data [flatten_asteroid(a) for a in all_asteroids] df pd.DataFrame(flat_data)这个函数的写法有三个要点一是用.get()方法取字典值避免键不存在时直接抛KeyError二是对嵌套比较深的结构比如close_approach_data做了两层防御先给空字典兜底再取值三是一次性把原始列表通过列表推导式转换成字典列表再交给DataFrame构造器。这样处理完的数据就是干干净净的表格结构可以直接做筛选和绘图。4.2 处理日期和缺失值NASA的接口数据质量算是相当高的但缺失值依然不可避免。比如某些小行星的close_approach_data字段为空列表清洗后对应的日期和速度字段就会是None。这时就需要根据分析目标决定处理策略如果做回归分析缺失值可能导致模型报错需要填充或丢弃如果只是做统计展示保留也无妨绘图时会自动跳过。日期字段的处理又是另一回事。原始日期是YYYY-MM-DD格式的字符串pandas读取后是object类型无法直接做时间序列分析。需要转换df[close_approach_date] pd.to_datetime( df[close_approach_date], errorscoerce )errorscoerce参数的作用是遇到无法解析的日期时填NaT而不是直接中断报错。这个参数在清洗任何类型数据时都值得记住它让你能先看到错误的全貌再决定怎么处理而不是让程序在第一个坏数据上就暴毙。我还习惯先查看数据类型总览和数据量再决定如何处理print(df.info()) print(df.isnull().sum())这两行代码能让你快速掌握全貌。数据量、字段类型、缺失分布一目了然。很多新手拿到数据就急着做可视化结果图出来发现坐标轴上的数据错乱、日期没排序往往都是栽在这两步检查上。4.3 数据筛选和排序处理完原始结构后最激动人心的时刻来了——看看哪些小行星最值得关注。一个典型的分析场景是找出最近距离地球最近的天体。不过close_approach_data里记录的是历史多次接近数据直接用当前记录排序可能得出不完整的结论所以我会先按日期筛选出最近一次接近再按距离排序。示例逻辑如下# 按接近日期排序取每个小行星最近的一次记录 df_sorted df.sort_values( close_approach_date, ascendingFalse ).drop_duplicates(name) # 查看最危险的10颗小行星 hazardous df_sorted[df_sorted[is_potentially_hazardous] True] top_hazardous hazardous.sort_values(diameter_max_km, ascendingFalse).head(10) print(top_hazardous[[name, diameter_max_km]])drop_duplicates(name)这一步是去重常用的手法——一个名称对应多行历史数据但统计每颗小行星时只需要保留最新状态。这里排序后去重的写法是先排序再调用去重保证保留的是每个名称下日期最新的一条逻辑上比先分组再取第一条更直观。这里能感受到清理数据的工作量往往大于拉取数据但这也正是把API原始输出变成可用信息的关键过程。数据清理决定了后续分析的上限。5. 可视化分析让数据开口说话5.1 用matplotlib绘制直径分布图有了干净的DataFrame画图就变得顺手了许多。以分析小行星直径分布为例matplotlib和seaborn组合非常高效import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize(10, 6)) sns.histplot(df[diameter_min_km].dropna(), bins50, kdeTrue) plt.xlabel(直径最小值公里) plt.ylabel(数量) plt.title(小行星直径分布) plt.show()直方图能快速揭示数据的整体形态。从实际运行结果来看大部分小行星直径集中在0.1到1公里之间少数几个超过5公里的属于极端值。这种长尾分布不是NASA独有的很多天文数据都有类似形态看到这种分布形态时千万别用均值来描述数据中心——推荐做法是报告中同时列出中位数和四分位数。如果嫌seaborn画图时字体太小可以通过pandas的绘图接口快速调整。注意中文字体在matplotlib里偶尔会显示成方框解决办法是加两行字体设置plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False这段代码在不同操作系统上表现不同Windows用户设置SimHei就行macOS用户改成Arial Unicode MSLinux用户通常需要自己装中文字体。我实际踩过这个坑之后养成了在画图脚本开头固定设置字体的习惯。5.2 绘制危险小行星的速度-直径关系进一步的分析可以做散点图看危险小行星的直径与接近速度之间是否存在相关性。从物理直觉来说直径和速度是两个相对独立的天体属性但从统计上验证这个过程本身就有趣plt.figure(figsize(12, 7)) scatter plt.scatter( xdf[diameter_max_km], ydf[relative_velocity_kph].astype(float), cdf[is_potentially_hazardous], cmapcoolwarm, alpha0.7, s30 ) plt.xlabel(最大直径公里, fontsize12) plt.ylabel(相对速度公里/小时, fontsize12) plt.title(小行星直径与相对速度关系, fontsize14) plt.colorbar(scatter, label是否潜在危险天体) plt.show()这段代码用c参数按是否危险着色的思路很实用——不用额外筛选数据颜色本身自动形成分组。速度字段在之前的清洗步骤中还是字符串所以这里做了astype(float)转换。如果你在画图时报错类型不匹配多半就是忘了这一步。从最终的图中能直观看到危险小行星暖色点分布在直径较大区域速度上没有明显聚类这个结论和官方数据描述是吻合的。5.3 保存图表和导出结果图表画好后保存和导出也是基本功。Python提供了丰富的导出格式选项我常用的一种组合是PNG用于快速预览PDF用于论文或报告SVG用于网页展示plt.savefig(asteroid_analysis.png, dpi150, bbox_inchestight) plt.savefig(asteroid_analysis.pdf, bbox_inchestight)同时处理好的数据也可以落盘保存方便下次分析直接读取不必重新请求APIdf.to_csv(asteroid_data.csv, indexFalse) df.to_excel(asteroid_data.xlsx, indexFalse)数据落盘时indexFalse这个参数是我反复强调的。默认情况下to_csv会把行索引也写进文件导致你重新读入时多出一个名为Unnamed: 0的列。这个小坑说大不大但确实会额外消耗时间在数据量大的时候尤其会让人头疼。6. 自动化与进阶玩法从手工到定时采集6.1 写一个自动采集脚本数据采集和清洗过程稳定后自然会产生自动化需求。凌晨和午夜的数据可能不同以近地天体为例新发现的小行星会被持续补充进数据库定时拉取能保证数据的新鲜度。最简单的自动化方案是写一个独立脚本然后交给系统定时任务去执行# nasa_daily.py import requests import pandas as pd import json from datetime import datetime, timedelta def fetch_apod(date_str): url https://api.nasa.gov/planetary/apod params {api_key: API_KEY, date: date_str} resp requests.get(url, paramsparams) return resp.json() def main(): today datetime.now().strftime(%Y-%m-%d) apod_data fetch_apod(today) output { title: apod_data.get(title), date: today, url: apod_data.get(url), explanation: apod_data.get(explanation) } with open(fapod_{today}.json, w, encodingutf-8) as f: json.dump(output, f, ensure_asciiFalse, indent2) if __name__ __main__: main()这个脚本的精妙之处在于if __name__ __main__这个入口保护——脚本被直接运行时执行main()被其他模块导入时则跳过避免副作用。JSON输出时加上ensure_asciiFalse和indent2前者保证中文不乱码后者让文件可读性翻倍。6.2 配置定时任务在常用的Windows和Linux系统上定时运行脚本的方案略有不同。Windows下用“任务计划程序”创建一个基本任务触发器设为每天固定时间操作为启动Python解释器并传入脚本路径。Linux或macOS下用crontab0 8 * * * cd /path/to/project /usr/bin/python3 nasa_daily.py这段cron表达式的含义是每天8点整先切换工作目录再执行脚本。切换目录这步相当重要因为如果你的脚本用相对路径写文件不切目录可能导致文件落在奇怪的位置。我实际跑定时任务时还配合日志输出把运行状态追加到一个文件里方便后期排查0 8 * * * cd /path/to/project /usr/bin/python3 nasa_daily.py run.log 21是追加而不是覆盖21表示把错误输出也写进同一个日志。这样跑一段时间后打开日志文件能清晰看到每次运行的结果有没有报错一目了然。定时任务出问题时日志是排查的第一现场。6.3 增量采集策略在数据量积累到一定程度后增量采集的思路会浮现出来。近地天体数据是全量查询接口每次拉全量数据有点浪费调用次数。一个务实的做法是每次拉取后记录本次获取的最新时间戳下次采集时只请求新数据。实现思路是构建一个状态文件import os import json STATE_FILE last_sync.json def load_state(): if os.path.exists(STATE_FILE): with open(STATE_FILE, r) as f: return json.load(f) return {} def save_state(state): with open(STATE_FILE, w) as f: json.dump(state, f)这个状态管理模式的本质是以空间换时间——把同步状态持久化到本地下次运行时无需从头拉取只取增量数据。对于日更频率的天文数据这种方式能把API请求量降低到原来的几十分之一也大大降低被限流的概率。7. 常见问题与错误排查速查表7.1 报错与解决方案一览以下是我实际使用过程中遇到的典型问题整理成一张速查表方便对照问题现象可能原因解决方案返回403错误API Key错误或未传递检查密钥是否复制完整确认请求参数中包含api_key返回429错误请求频率过高触发限流在请求之间增加sleep延长间隔时间返回404错误请求的路径或参数不对仔细对照API文档确认资源路径和参数名完全一致JSON解析报错响应内容不是合法JSON先打印response.text查看内容可能是网关返回的HTML错误页日期字段为NaN日期格式不受pandas识别用errorscoerce先找出问题值再检查原始数据格式速度字段无法计算字段类型是字符串或对象用astype(float)转换数值类型图表中文显示方块系统缺少中文字体支持设置plt.rcParams[font.sans-serif]指定已安装的中文字体超时无返回网络连接问题或接口过慢增加timeout参数并用重试逻辑覆盖7.2 排查思路分享遇到报错时我一般遵循以下排查顺序第一步先看状态码和响应体内容。response.status_code是目前最好判断问题的手段200代表正常4开头的状态码代表请求有问题5开头代表对方服务端异常。这一步能排除至少一半的问题。第二步确认请求参数完全匹配文档。NASA的接口对参数名大小写敏感StartDate写成start_date可能会被直接忽略导致返回默认数据范围表面上不报错但数据不对。这类问题最隐蔽排查时要把请求URL完整打印出来和文档逐字符比对。第三步检查数据结构。如果是解析时报错把返回的JSON最小化后人工浏览一遍确认所有键名和层级都和自己代码里的假设一致。接口更新后字段变动的情况并不罕见代码跑久了突然出问题十有八九是这里的原因。8. 结合个人经验的几点建议最后整理几条我个人在这个项目上的体会。第一每次请求务必带上timeout参数。不设置默认超时的程序在某个接口抽风时会无限等待这时候整条采集链路都会被卡住。多花一个参数字节换来的是程序的确定性。第二密钥管理要规范化。我倾向于把密钥放在环境变量里而不是写死在代码中这样在不同设备间同步代码时不用担心泄漏。在没有环境变量工具支持的场景下至少也应该把密钥放到单独的配置文件中并在.gitignore里排除掉它。第三处理嵌套JSON时不要试图一次性写一个“万能解析函数”。先把数据结构摸清楚再针对性地抽取字段代码看着啰嗦但稳定可靠。我之前试过用递归函数自动展平任意JSON结果在字段名冲突和类型混合问题上踩了不少坑性价比实在不高。第四不管是开发还是测试先小批量验证再全量采集。比如先请求一页数据确认解析逻辑正确再放开循环拉全量。多花一分钟的验证能避免你拿着错误逻辑跑完全部数据后才发现清洗结果全不对——那种返工的感觉经历一次就够了。按照这套流程走下来你从注册到做出第一张完整的数据分析图通常只需要一个下午的时间。后面想深入的方向也很多比如把火星天气数据接入到本地气象面板或者用地球影像接口做特定位置的植被变化分析又或者给每日天文图片写一个自动发送到邮箱的定时任务。数据和思路都摆在这里接下来就看你想玩出什么花样了。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号