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

使用Python3与OpenSea API获取NFT集合完整持有者列表及对应ETH地址

Opensea Aethir Wars NFT持有者列表爬取问题修复

问题描述

尝试获取Opensea.io上Aethir Wars NFT集合的持有者列表,所需数据包含持有人信息、所持NFT详情及对应的ETH地址。目前已能获取到部分持有者及其地址,但输出列表存在缺失不全的问题。另外由于未经过购买直接转账的NFT的Last_Sale参数为null,已额外添加if判断处理该场景,需要解决列表不全的问题。

现有问题代码

import requests

url = "https://api.opensea.io/api/v1/assets"
api_key = "api key"
col = 'reapers'

def print_owners(race, offset):
    querystring = {'order_by': 'name', 'order_direction': 'asc', 'offset': offset, 'limit': '50',
                   'collection': col, 'X-API-KEY': api_key}
    response = requests.get(url, params=querystring)
    data = response.json()
    i = 0
    for each_asset in data['assets']:
        try:
            if race in data['assets'][0]['name']:
                if data["assets"][i]["last_sale"] is None:
                    print(data["assets"][i]["name"] + ': '
                          + data["assets"][i]["sell_orders"][0]["maker"]["address"])
                else:
                    print(data["assets"][i]["name"] + ': '
                          + data["assets"][i]["last_sale"]["transaction"]["from_account"]["user"]["username"])
        except TypeError:
            pass
        i += 1


x = range(0, 600, 50)

for stuff in x:
    try:
        print_owners(race='Reaper', offset=str(stuff))
    except KeyError:
        pass

    try:
        print_owners(race='Android', offset=str(stuff))
    except KeyError:
        pass

    try:
        print_owners(race='Goblin', offset=str(stuff))
    except KeyError:
        pass

数据缺失的核心原因

  • 逻辑判断错误:原代码用if race in data['assets'][0]['name']判断整页数据是否符合种族要求,只要当前页第一个资产不属于对应种族,整页50条数据全部跳过,直接丢失大量符合要求的条目
  • 取数逻辑错误:没有直接使用接口返回的owner字段获取当前持有者地址,反而绕路去取sell_orders(只有挂单的资产才有该字段,没挂单的直接报错跳过)和last_sale的转出方(这是上次交易的卖家,不是当前持有者,数据完全不对)
  • 接口调用格式错误:Opensea v1 API要求X-API-KEY放在请求头中,原代码把key放在查询参数里,会触发接口限流或者返回不完整数据
  • 异常捕获过于宽泛:所有报错直接静默跳过,无法排查漏数原因
  • 分页范围不足:仅遍历0-600的offset,如果集合NFT总量超过600,超出部分完全无法获取

修复方案

直接调用接口返回的标准owner字段获取当前持有者信息,修正判断逻辑和参数传递规则,优化异常捕获:

import requests

url = "https://api.opensea.io/api/v1/assets"
api_key = "替换为你自己的API_KEY"
col = 'reapers'
# 可根据集合实际总量调整最大offset
MAX_OFFSET = 2000

def print_owners(race, offset):
    querystring = {
        'order_by': 'name',
        'order_direction': 'asc',
        'offset': offset,
        'limit': '50',
        'collection': col
    }
    # API KEY放到请求头
    headers = {"X-API-KEY": api_key}
    response = requests.get(url, params=querystring, headers=headers)
    # 先判断接口返回状态
    if response.status_code != 200:
        print(f"接口请求失败,状态码{response.status_code},offset={offset}")
        return
    data = response.json()
    if 'assets' not in data:
        return
    for each_asset in data['assets']:
        try:
            # 对当前遍历的资产做种族判断,不是整页第一个
            asset_name = each_asset.get('name', '')
            if race in asset_name:
                # 直接取当前持有者地址,不受last_sale、sell_orders影响
                owner_addr = each_asset['owner']['address']
                # 可以额外取owner的用户名,没有的话留空
                owner_name = each_asset['owner'].get('user', {}).get('username', '无用户名')
                print(f"{asset_name}: 持有者地址{owner_addr}, 用户名{owner_name}")
        except Exception as e:
            # 打印错误方便排查,不要直接跳过
            print(f"处理资产{each_asset.get('id', '未知ID')}出错: {str(e)}")

if __name__ == '__main__':
    race_list = ['Reaper', 'Android', 'Goblin']
    for offset in range(0, MAX_OFFSET, 50):
        for race in race_list:
            print_owners(race=race, offset=offset)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:48:00