掌握USDA食品数据API分页获取完整营养信息教程

掌握USDA食品数据API分页获取完整营养信息教程

本教程详细介绍了如何通过Python有效地从USDA食品数据API获取完整的营养事实数据。针对API默认返回结果受限(如50条)的问题,文章深入探讨了API分页机制,并提供了利用pageSize和pageNumber参数迭代获取所有数据项的解决方案。教程包含示例代码、错误处理和最佳实践,旨在帮助开发者构建稳定、高效的数据采集流程。

深入理解API分页机制与USDA食品数据API实践

在使用外部api获取数据时,开发者经常会遇到返回结果数量受限的情况。这通常是由于api采用了分页(pagination)机制,旨在优化性能、减少带宽消耗并防止单次请求返回过大数据量。美国农业部(usda)的食品数据中心(food data central, fdc)api也不例外,其搜索接口在默认情况下可能只返回少量结果(例如50条)。本教程将详细讲解如何识别并处理这种分页机制,从而获取完整的usda食品营养数据。

识别API分页

当通过API进行数据查询,但发现返回的数据量远低于预期时,首先应查阅该API的官方文档。对于USDA FDC API,其文档(例如SwaggerHub上的Food Data Central API)会明确指出搜索结果是分页的。在API响应中,通常会包含指示当前页码(currentPage)和总页数(totalPages)的字段。此外,文档还会说明控制分页行为的参数,例如:

pageSize: 每页返回结果的最大数量。USDA API允许将此参数设置为最大200。pageNumber: 指定要获取的页码。

理解这些参数是获取全部数据的关键。

分页获取完整数据的实现

为了获取所有符合条件的食品数据,我们需要编写一个循环,迭代请求每一页的数据,并将它们累积起来。以下是使用Python requests 库实现此逻辑的示例代码:

import requestsimport jsonimport pandas as pddef get_all_usda_foods(query_term, api_key, page_size=200):    """    从USDA食品数据API分页获取所有符合查询条件的食品数据。    参数:    query_term (str): 查询的食品名称或关键词。    api_key (str): USDA API的授权密钥。    page_size (int): 每页返回的结果数量,最大为200。    返回:    list: 包含所有食品数据字典的列表,如果发生错误则返回None。    """    all_foods = []    # 构造初始URL,设置每页大小    base_url = f"https://api.nal.usda.gov/fdc/v1/foods/search?api_key={api_key}&query={query_term}&pageSize={page_size}"    with requests.Session() as session:  # 使用requests.Session保持连接,提高效率        try:            # 第一次请求,获取总页数            print(f"Fetching initial page for query: '{query_term}'")            response = session.get(base_url, timeout=10)            response.raise_for_status()  # 检查HTTP请求是否成功            api_response = response.json()            # 检查API响应结构,确保'foods'和'totalPages'存在            if "foods" not in api_response or "totalPages" not in api_response:                print("Error: 'foods' or 'totalPages' not found in initial API response.")                return None            all_foods.extend(api_response["foods"])            total_pages = api_response["totalPages"]            print(f"Total pages to fetch: {total_pages}")            # 从第二页开始循环获取所有数据            for page_num in range(2, total_pages + 1):                print(f"Fetching page {page_num}/{total_pages}...")                page_url = f"{base_url}&pageNumber={page_num}"                page_response = session.get(page_url, timeout=10)                page_response.raise_for_status()                page_api_response = page_response.json()                if "foods" in page_api_response:                    all_foods.extend(page_api_response["foods"])                else:                    print(f"Warning: 'foods' not found in response for page {page_num}.")                    break # 如果某一页没有'foods',可能表示数据结束或API行为异常        except requests.exceptions.HTTPError as http_err:            print(f"HTTP error occurred: {http_err} - Status Code: {http_err.response.status_code}")            return None        except requests.exceptions.ConnectionError as conn_err:            print(f"Connection error occurred: {conn_err}")            return None        except requests.exceptions.Timeout as timeout_err:            print(f"Request timed out: {timeout_err}")            return None        except requests.exceptions.RequestException as req_err:            print(f"An unexpected request error occurred: {req_err}")            return None        except json.JSONDecodeError as json_err:            print(f"Failed to decode JSON response: {json_err}")            print(f"Response content: {response.text[:500]}...") # 打印部分响应内容辅助调试            return None        except Exception as e:            print(f"An unexpected error occurred: {e}")            return None    return all_foods# 使用示例if __name__ == "__main__":    API_KEY = "YOUR_USDA_API_KEY" # 替换为你的USDA API密钥    search_term = "raw fruit" # 示例查询词    print(f"Starting data retrieval for '{search_term}'...")    food_items_data = get_all_usda_foods(search_term, API_KEY)    if food_items_data:        print(f"nSuccessfully retrieved {len(food_items_data)} food items.")        # 将数据转换为Pandas DataFrame并导出到Excel        processed_data = []        for item in food_items_data:            row = {"Description": item.get("description", "N/A")}            for nutrient in item.get("foodNutrients", []):                nutrient_name = nutrient.get("nutrientName")                nutrient_value = nutrient.get("value")                if nutrient_name and nutrient_value is not None:                    row[nutrient_name] = nutrient_value            processed_data.append(row)        df = pd.DataFrame(processed_data)        # 清理列名,处理重复营养素(如果存在)        # 这里只是一个简单的处理,实际应用中可能需要更复杂的逻辑        df = df.loc[:,~df.columns.duplicated()]         output_filename = f'{search_term.replace(" ", "_")}_nutritional_facts.xlsx'        df.to_excel(output_filename, index=False)        print(f"Data exported to {output_filename}")    else:        print("Failed to retrieve food data.")

代码解析与注意事项

get_all_usda_foods 函数:

参数: 接收查询关键词 (query_term)、API密钥 (api_key) 和可选的 page_size。requests.Session(): 使用 requests.Session 可以复用底层的TCP连接,对于多次请求同一个域名,这能显著提高性能。初始请求: 首先发送一个请求来获取第一页的数据,并从中提取 totalPages。这是确定需要循环多少次的关键。循环获取: 从第二页开始,循环直到 totalPages。在每次循环中,构造带有 pageNumber 参数的URL,发送请求,并将返回的 foods 数据添加到 all_foods 列表中。错误处理: 集成了 try-except 块来捕获可能发生的网络错误(如 HTTPError, ConnectionError, Timeout)和JSON解析错误(JSONDecodeError),提高了代码的健壮性。当发生错误时,函数会打印错误信息并返回 None。response.raise_for_status(): 这是一个非常有用的方法,如果HTTP请求返回了错误状态码(例如4xx或5xx),它会抛出 HTTPError 异常。

数据处理与导出:

获取到所有 food_items_data 后,代码遍历每个食品项,提取其描述和所有营养成分。将这些数据组织成字典列表,然后使用 pandas.DataFrame 转换为数据框。df.loc[:,~df.columns.duplicated()] 这一行用于处理在数据转换过程中可能出现的重复列名(例如,如果API响应中同一个营养素名称出现了多次,尽管通常不会)。这只是一个简单的去重方法,在实际应用中可能需要更复杂的逻辑来合并或区分重复数据。最后,使用 df.to_excel() 方法将数据框导出到Excel文件,index=False 表示不将DataFrame的索引写入Excel。

API密钥安全:

在示例代码中,API_KEY 直接写在代码中。在实际生产环境中,绝不应将API密钥硬编码到代码中或直接暴露在公共仓库中。应使用环境变量、配置文件或密钥管理服务来安全地存储和访问API密钥。

请求频率与限流:

虽然USDA API文档中没有明确提及严格的速率限制,但频繁或高速的请求可能会导致IP被暂时封禁。在处理大量数据时,可以考虑在请求之间添加短暂的延时(例如 time.sleep(0.1)),以模拟更自然的用户行为,减少被限流的风险。

超时设置:

timeout=10 参数为每个请求设置了10秒的超时时间。这是一个良好的实践,可以防止程序因网络问题长时间挂起。根据网络环境和API响应速度,可以适当调整此值。

总结

通过本教程,我们学习了如何识别和应对API分页问题,特别是针对USDA食品数据API。核心策略是利用API文档中提供的 pageSize 和 pageNumber 参数,通过迭代请求来获取完整数据集。结合 requests.Session 优化性能、完善的错误处理以及将数据导出到Pandas DataFrame和Excel的实践,开发者可以构建出高效、健壮的数据采集解决方案。在任何API集成中,仔细阅读API文档、理解其工作原理并实施适当的错误处理和安全措施始终是成功的关键。

以上就是掌握USDA食品数据API分页获取完整营养信息教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1369075.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 09:20:24
下一篇 2025年12月14日 09:20:38

相关推荐

  • Python利用USDA API获取完整营养数据:深度解析分页机制

    本教程旨在解决使用USDA食品数据中心(FDC)API时遇到的数据分页限制问题,特别是默认仅返回50条结果的情况。文章将详细解释API分页机制,并通过Python代码示例演示如何有效地利用pageSize和pageNumber参数,结合请求会话和错误处理,实现完整数据集的迭代获取与处理,最终导出至E…

    好文分享 2025年12月14日
    000
  • 深入理解与实现USDA FDC API数据分页获取

    本文旨在解决通过Python API获取USDA FDC营养数据时遇到的结果限制问题。我们将详细讲解API分页机制,介绍如何利用pageSize和pageNumber参数,并通过迭代请求实现完整数据集的检索,确保用户能够高效、准确地获取所有目标数据。 1. 理解API分页机制 在使用第三方API时,…

    2025年12月14日
    000
  • 计算图像像素平均亮度时出现不一致问题的解决方案

    本文旨在解决在使用OpenCV计算不同图像像素平均亮度时出现不一致的问题。通过分析问题代码,并结合实际案例,提供了一种更准确的计算图像平均亮度的方法,重点在于使用 cv2.imread 正确加载图像,并利用 numpy 提供的 mean() 函数进行计算,避免了潜在的类型转换和溢出问题。 在图像处理…

    2025年12月14日
    000
  • Python中字典怎么遍历 Python中字典遍历教程

    遍历字典默认是遍历键,可用.values()遍历值,.items()遍历键值对;遍历时修改字典会报错,应先复制键或用推导式生成新字典;大型字典推荐直接使用.keys()、.values()、.items()获取视图对象以节省内存;Python 3.7+字典有序,3.6及以前无序,需顺序时用Order…

    2025年12月14日
    000
  • python怎么读取csv文件_python数据处理基础教程

    首选pandas库读取CSV文件,因其功能强大且操作高效,适合数据分析;对于简单行操作,可使用内置csv模块,更加轻量灵活。 Python处理CSV文件,最直接也最常用的方式就是借助`pandas`库。它提供了一套高效且功能强大的工具集,能让你轻松地读取、操作和分析CSV数据。当然,如果只是简单的行…

    2025年12月14日
    000
  • 图像平均亮度计算:从不一致到精确的实践指南

    本文探讨了在使用OpenCV和NumPy处理不同图像时,手动计算像素平均亮度可能导致结果不一致的问题。通过分析原始代码中手动求和与像素调整的潜在弊端,本教程展示了如何利用cv2.imread的正确参数组合加载图像,并直接使用numpy.ndarray.mean()方法进行高效且准确的平均亮度计算,从…

    2025年12月14日
    000
  • 多算法聚类结果的合并策略与SQL实现:基于连通分量的传递闭包方法

    本文探讨了如何合并来自不同聚类算法、但作用于同一数据集的聚类结果。当不同算法的集群通过共享相同数据项而存在重叠时,需要将这些重叠集群进行传递性合并。文章将阐述此问题本质上是图论中的连通分量发现,并提供基于SQL和Python/PySpark的解决方案,重点讲解其逻辑、实现步骤及注意事项,以生成统一的…

    2025年12月14日
    000
  • 图像亮度计算中的OpenCV读取与Numpy优化实践

    本文探讨了在使用OpenCV和Numpy计算图像像素平均亮度时可能遇到的不一致问题,特别是在处理不同图像数据集或16位图像时。通过分析不准确的图像加载方式和手动像素值调整,文章提出并演示了采用cv2.imread的正确标志组合以及直接利用numpy.mean()方法进行高效且精确亮度计算的优化方案,…

    2025年12月14日
    000
  • Django模型中高效动态获取关联字段值并构建字典

    本教程详细阐述了在Django中如何高效地从主模型动态获取所有通过ForeignKey关联的子模型的特定字段值,并将其组织成一个结构化字典。通过利用ReverseManyToOneDescriptor进行模型内省,并结合在关联模型中自定义dump方法,我们能够自动化数据聚合过程,避免繁琐的手动查询,…

    2025年12月14日
    000
  • Django模型关联数据动态提取与字典化:构建通用数据导出方法

    本教程旨在解决Django中从主模型动态高效地获取所有反向关联模型数据并将其组织成字典的挑战。通过利用模型自省机制识别反向外键,并结合关联模型上定义的统一数据提取方法,我们能够自动化地收集和格式化相关数据,避免手动编写大量重复查询代码,从而提高代码的简洁性和可维护性。 在django应用开发中,当一…

    2025年12月14日
    000
  • 高效获取UniProt数据库条目ID:应对动态加载与API应用实践

    本教程旨在解决从UniProt网站抓取条目ID时,因页面内容动态加载导致传统BeautifulSoup解析失败的问题。我们将深入分析失败原因,并提供一个更稳定、高效的解决方案:利用UniProt官方REST API直接获取所需数据,避免复杂的网页解析,确保数据提取的准确性和可靠性。 网页动态加载内容…

    2025年12月14日
    000
  • 高效获取Django关联模型数据字典:元编程与自定义方法

    本教程旨在解决如何高效地从Django父模型实例中,动态收集其所有关联模型(通过ForeignKey反向引用)的特定字段值,并将其整合到一个简洁的字典中。我们将通过利用Python的元编程技术来识别反向外键关系,并结合关联模型上的自定义方法来提取所需数据,从而避免手动逐一查询的繁琐与低效。 引言:高…

    2025年12月14日
    000
  • UniProt动态内容抓取:利用REST API高效获取生物序列条目ID教程

    本教程旨在解决从UniProt数据库动态加载页面抓取条目ID的常见问题。当传统的requests和BeautifulSoup组合无法获取JavaScript渲染的数据时,文章详细介绍了如何利用UniProt官方提供的REST API进行高效、可靠的数据提取。通过实例代码,演示了查询特定条目和模拟下载…

    2025年12月14日
    000
  • Django模型反向关联数据高效字典化教程

    本教程详细阐述了如何在Django中高效地将主模型的所有反向关联模型数据聚合到一个字典中。通过利用ReverseManyToOneDescriptor动态识别反向外键关系,并结合相关模型自定义的dump方法,我们能够自动化地提取指定字段的值,从而避免手动查询每个关联模型,极大地提升了数据获取的灵活性…

    2025年12月14日
    000
  • Python中复杂数据结构属性变更的级联更新机制

    本文探讨了在Python中,当复杂嵌套对象内部属性发生变化时,如何实现上层派生数据结构的自动更新。通过引入分层更新策略,结合@property装饰器和显式更新方法,构建了一个能够响应内部对象状态变化的级联更新机制,避免了手动调用更新方法的繁琐,提升了代码的健壮性和可维护性。 理解问题:为何属性变更未…

    2025年12月14日
    100
  • Python面向对象设计:管理嵌套对象属性变化与自动更新机制

    本文探讨了在Python中处理复杂嵌套对象结构时,如何确保当内部对象属性发生变化时,外部聚合对象能够自动感知并更新其状态。通过分析一个DataFrame构建器的实际案例,我们将展示如何利用显式更新方法和分层设计,实现高效、可维护的数据同步机制,避免手动触发更新的繁琐。 问题背景:嵌套对象属性变化的挑…

    2025年12月14日
    000
  • 图像平均亮度计算不一致性解析与Numpy优化实践

    本文旨在解决图像处理中计算平均亮度时出现的数值不一致问题。通过分析原始代码中手动计算平均值及处理零像素的策略,我们发现利用Numpy数组内置的mean()方法能显著简化代码、提高计算准确性和效率。本教程将详细介绍如何采用更简洁、可靠的方式计算图像的平均亮度,并提供优化后的代码示例及最佳实践建议。 图…

    2025年12月14日
    000
  • Python函数设计:避免循环引用与提升模块化

    本文探讨了Python函数设计中常见的循环引用问题,尤其是在GUI应用中计算总价、税费和服务费的场景。通过分析一个RecursionError案例,我们展示了如何通过参数传递和函数职责分离来重构代码,有效避免无限递归,提升代码的可读性、可维护性和模块化程度。 Python函数设计与循环引用问题解析 …

    2025年12月14日
    000
  • Python如何读取csv文件_Python读取csv文件方法总结

    使用csv模块和pandas是Python读取CSV文件最常用的方法;csv适合基础逐行处理,pandas则擅长高效的数据分析与大规模操作,结合二者可应对绝大多数场景。 Python读取CSV文件,最常用且高效的方式莫过于使用内置的 csv 模块,它提供了基础而强大的解析能力,尤其适合处理结构相对简…

    2025年12月14日
    000
  • python怎么字符串拼接_python多种字符串连接方式

    Python字符串拼接应根据场景选择方法:f-string适用于变量嵌入和格式化,.join()适合高效连接大量字符串,避免在循环中使用+操作符以防止性能问题。 Python中拼接字符串的方式远不止一种,从最直观的 + 操作符,到高效的 .join() 方法,再到现代且强大的f-string,以及传…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信