3. 数据采集入门:使用Python调用RPC节点获取区块数据(Web3.py基础)

好,咱们正式开始动手了。

前面两章聊了聊链上数据的价值,也画了画筹码分布的理论框架。但说一千道一万,数据从哪来?

这一章,我就带你亲手把数据从链上“拽”下来。

说白了,我们要干的事就一件:让Python跟以太坊节点对话,把区块、交易、日志这些原始数据拿到本地

3.1 为什么是Web3.py?

你可能会问:市面上那么多工具,为什么非要用Web3.py?

我个人习惯是:能用Python解决的,绝不用别的。Web3.py是Python生态里最成熟的以太坊交互库,没有之一。它封装了JSON-RPC协议,你不需要自己拼HTTP请求、解析十六进制返回值——这些脏活累活,库都帮你干了。

我在项目中遇到过好几次,团队里有人用curl直接调RPC接口,结果被各种数据格式转换搞得焦头烂额。后来换成Web3.py,代码量直接砍掉一半。

3.2 环境准备:装好你的工具箱

嗯,这里要注意:Python版本最好3.8以上。我建议你新建一个虚拟环境,别把全局环境搞乱了。

# 创建虚拟环境(我习惯用venv)
python -m venv web3_env
source web3_env/bin/activate  # Mac/Linux
# web3_env\Scripts\activate   # Windows

# 安装Web3.py
pip install web3

# 验证安装
python -c "from web3 import Web3; print(Web3.__version__)"

看到版本号输出,说明装好了。

3.3 连接节点:你的链上入口

有了Web3.py,下一步就是连节点。节点分两种:

  • 自建节点:自己跑Geth或Nethermind,数据全、无限制,但维护成本高
  • 第三方节点:Infura、Alchemy、QuickNode这些服务商,开箱即用

我个人建议:刚开始用Infura就够了。免费套餐每天10万次请求,做课程实验绰绰有余。

from web3 import Web3

# 连接Infura节点(记得换成你自己的API Key)
infura_url = "https://mainnet.infura.io/v3/YOUR_API_KEY"
w3 = Web3(Web3.HTTPProvider(infura_url))

# 检查是否连接成功
if w3.is_connected():
    print("✅ 连接成功!当前区块高度:", w3.eth.block_number)
else:
    print("❌ 连接失败,检查网络或API Key")

你想想看,就这么几行代码,你已经跟以太坊主网连上了。是不是挺简单的?

💡 小技巧: 如果你不想暴露API Key,可以把它设成环境变量。我习惯在项目根目录放一个.env文件,用python-dotenv加载。

3.4 获取区块数据:从最新区块开始

连接成功,咱们来抓点真东西。

# 获取最新区块
latest_block = w3.eth.get_block('latest')
print("区块号:", latest_block['number'])
print("时间戳:", latest_block['timestamp'])
print("交易数量:", len(latest_block['transactions']))

# 获取指定区块(比如第18000000号区块)
block = w3.eth.get_block(18000000, full_transactions=True)
print("区块哈希:", block['hash'].hex())
print("矿工地址:", block['miner'])
print("Gas使用量:", block['gasUsed'])

这里有个坑,我踩过:get_block的第二个参数full_transactions,默认是False。如果设为True,它会返回完整的交易对象,而不是交易哈希列表。数据量会大很多,请求也慢一些。

我曾经在分析某个DeFi项目时,一口气拉了1000个区块的完整交易数据,结果等了快10分钟。后来学乖了:先拿哈希列表,需要时再按需拉取具体交易

3.5 解析交易数据:读懂链上每一笔操作

区块拿到了,交易也拿到了。但这些十六进制数据到底什么意思?

咱们来拆解一笔典型的以太坊转账交易:

# 获取最新区块的第一笔交易
block = w3.eth.get_block('latest')
tx_hash = block['transactions'][0]  # 注意:这里返回的是哈希,不是完整交易
tx = w3.eth.get_transaction(tx_hash)

print("交易哈希:", tx['hash'].hex())
print("发送方:", tx['from'])
print("接收方:", tx['to'])
print("转账金额(ETH):", w3.from_wei(tx['value'], 'ether'))
print("Gas价格(Gwei):", w3.from_wei(tx['gasPrice'], 'gwei'))
print("Nonce:", tx['nonce'])
print("输入数据:", tx['input'][:66] + "...")  # 截取前66个字符

你看,fromto就是转账双方地址,value是金额(单位是Wei,我用from_wei转成了ETH)。input字段比较特殊——如果是普通转账,它通常是0x;如果是合约调用,里面就藏着函数签名和参数。

🔑 核心概念: 链上数据的最小单位是Wei(1 ETH = 10^18 Wei)。所有金额计算,我建议都用Wei做单位,只在展示时转成ETH。浮点数精度问题,你懂的。

3.6 获取交易收据:确认交易状态

光有交易还不够,你还得知道这笔交易到底执行成功了没有。这时候就需要交易收据(Transaction Receipt)

# 获取交易收据
receipt = w3.eth.get_transaction_receipt(tx_hash)

print("区块号:", receipt['blockNumber'])
print("Gas实际消耗:", receipt['gasUsed'])
print("状态:", "成功 ✅" if receipt['status'] == 1 else "失败 ❌")
print("日志数量:", len(receipt['logs']))

status字段是1还是0,直接告诉你这笔交易有没有回滚。我在做链上监控时,第一件事就是过滤掉status=0的交易——那些失败的交易,数据没有分析价值。

3.7 实战:批量抓取最近10个区块

理论讲完了,咱们来点实战。下面这段代码,会抓取最近10个区块的概要信息:

from web3 import Web3
from datetime import datetime

w3 = Web3(Web3.HTTPProvider("https://mainnet.infura.io/v3/YOUR_API_KEY"))

current_block = w3.eth.block_number
print(f"当前区块高度:{current_block}")
print("-" * 60)

for i in range(10):
    block_num = current_block - i
    block = w3.eth.get_block(block_num)
    
    # 时间戳转人类可读格式
    timestamp = datetime.fromtimestamp(block['timestamp'])
    
    print(f"区块 #{block_num}")
    print(f"  时间:{timestamp}")
    print(f"  交易数:{len(block['transactions'])}")
    print(f"  Gas使用率:{block['gasUsed'] / block['gasLimit'] * 100:.1f}%")
    print()

这段代码我经常用来做“链上温度计”——如果Gas使用率持续高于90%,说明网络很拥堵,这时候做交易要小心了。

3.8 避坑指南:我踩过的那些坑

最后,分享几个我实战中遇到的坑:

  • 请求频率限制:Infura免费版每秒最多5次请求。我曾经写了个循环抓1000个区块,结果直接被封了10分钟。解决方案:加time.sleep(0.3),或者用Alchemy(免费版每秒330次请求)。
  • 数据格式:Web3.py返回的哈希值都是HexBytes类型,不能直接当字符串用。记得调用.hex()方法转换。
  • 大区块处理:有些区块包含上千笔交易,一次性拉取完整数据会非常慢。我建议先拉取交易哈希列表,再分批处理。
  • 节点同步延迟:你查到的“最新区块”可能比实际链上慢几秒。做实时监控时,记得留出6-12个区块的确认时间。
⚠️ 重要提醒: 永远不要在代码里硬编码你的API Key!我见过有人把代码传到GitHub公开仓库,结果API Key被滥用,一天跑了100万次请求,账单直接爆了。用环境变量或者配置文件管理密钥。

3.9 本章知识体系

下面这张图,帮你理清本章的核心逻辑:

数据采集入门:核心流程 1. 环境准备 Python 3.8+ → 安装 Web3.py → 获取 API Key 2. 连接节点 Web3(HTTPProvider) → w3.is_connected() 3a. 获取区块 get_block() → 区块头 + 交易列表 3b. 获取交易 get_transaction() → 交易详情 4. 交易收据 get_transaction_receipt() → 状态 / Gas / 日志 5. 数据解析与存储 from_wei() / hex() → CSV / 数据库

这张图把整个数据采集流程串起来了。从环境准备到连接节点,再到获取区块、交易、收据,最后解析存储——每一步都是下一章分析的基础。

好了,这一章的内容就到这。代码不多,但都是实打实能跑的东西。你最好打开编辑器,跟着敲一遍。光看是学不会的,动手才是硬道理。


专注资料整理