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

如何从OpenSea API返回的NFT数据正确构造按集合划分的pandas DataFrame

问题根因

原代码运行不符合预期,核心问题有4个:

  • 遍历逻辑错误:使用zip(token_id, collections)将token_id和集合地址按位置配对,2个集合地址仅匹配前2个token_id,总共只发起2次接口请求,因此仅返回2行有效数据,完全没有实现「单集合下遍历所有token」的逻辑
  • 列名未做标准化:不同NFT集合返回的trait_type存在大小写差异、前后冗余空格等格式问题,直接作为列名会生成Background/background这类语义重复的冗余列
  • 数据未按集合拆分:所有接口返回的特征数据统一存入同一个列表,没有按合约地址做分组隔离,无法生成单集合独立的DataFrame
  • 缺少边界处理:没有兼容接口请求失败、字段缺失的异常场景,容易触发运行中断
修正实现方案

实现逻辑:

  1. 外层按集合合约地址遍历,每个集合单独维护自己的特征存储列表
  2. 内层遍历当前集合下的所有token_id,逐个请求接口获取特征数据
  3. 对所有拿到的trait_type做标准化处理:统一去除首尾空格、统一单词首字母大写格式,从根源消除大小写/格式不一致导致的冗余列
  4. 每个集合的所有token特征收集完成后,统一转成DataFrame,pandas会自动对齐特征列,对缺失的特征值填充NaN

完整修正代码如下:

import pandas as pd
import requests
from collections import defaultdict

# 基础配置
collections = [
    "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D",
    "0x8a90cab2b38dba80c64b7734e58ee1db38b8992e"
]
token_id_range = range(1, 10) # 可根据集合实际总供应量调整遍历范围
opensea_headers = {"X-API-KEY": "替换为你自己的OpenSea API_KEY"}

# 按集合维度存储特征数据,key为合约地址,value为该集合下所有token的特征字典列表
collection_trait_map = defaultdict(list)

for contract_address in collections:
    for t_id in token_id_range:
        try:
            url = f"https://api.opensea.io/api/v1/asset/{contract_address}/{t_id}/?include_orders=false"
            resp = requests.get(url, headers=opensea_headers, timeout=10)
            resp.raise_for_status()
            traits_list = resp.json()['traits']
            
            # 重构特征字典,同步标准化特征列名
            trait_dict = {}
            for trait in traits_list:
                # 列名标准化:去前后空格、统一首字母大写,解决格式不一致导致的冗余列问题
                std_trait_name = trait['trait_type'].strip().title()
                trait_dict[std_trait_name] = trait['value']
            
            collection_trait_map[contract_address].append(trait_dict)
        except Exception as e:
            print(f"获取合约{contract_address}下token#{t_id}数据失败: {str(e)}")
            continue

# 生成每个集合独立的DataFrame
collection_df_map = {}
for contract, trait_data in collection_trait_map.items():
    df = pd.DataFrame(trait_data)
    collection_df_map[contract] = df
    # 可按需打印预览结果
    print(f"=== 合约{contract}特征表预览 ===")
    print(df.head())
使用说明
  • 最终生成的collection_df_map为字典结构,传入对应合约地址即可获取该集合独立的特征DataFrame,例如调用collection_df_map["0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D"]即可拿到BAYC集合的特征表
  • 列名标准化逻辑可根据业务需求调整,如果存在同语义不同命名的特征(如Mouth和Lip实际指向同一特征),可增加自定义映射字典做统一替换
  • 可根据OpenSea接口的限流规则增加请求间隔,避免触发访问限制
  • 输出的DataFrame结构和预期完全一致,缺失特征自动填充NaN

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:45:34