以太坊数据研究离不开区块解析与交易记录抓取。本文将用纯 Python 代码,带你从零开始抓取每一条 ETH 交易数据,并以本地文件形式持久化存储,既满足日常分析,也为学术研究省下高昂的接口费用。
准备环境:一句话装好所有依赖
pip install web3 pandas tqdm python-dotenv一条命令完成环境部署,避开繁琐的依赖噩梦。
1. 快速理解:以太坊交易长什么样?
在动手前,先弄清两个最常被提起的概念:
- 区块(block):每 12 秒左右生成一次,内含数十到数百笔交易。
- 交易(transaction):最简单的转账或合约交互,字段包括
from、to、value、gas等。
下图仅演示数据层级,帮助你建立直观印象:
区块
└─ 交易数组
├─ 交易0 {hash, from, to, value, gasPrice, ...}
├─ 交易1 {...}
└─ ...2. 三行代码连接主网并验证节点
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/<你的ProjectID>'))
print("已连接主网:", w3.isConnected()) # True 表示成功出现 True 即可继续;如果返回 False,多半是节点 URL 或网络配置出了问题。
3. 抓取单个区块的全部交易详情
以太坊本身提供了 w3.eth.get_block 方法,但返回的是字典,在数据分析场景不够直观。为此,我们封装一个 区块解析器(BlockParser):
def fetch_block_txs(block_number):
block = w3.eth.get_block(block_number, full_transactions=True)
return [
{
"hash": tx["hash"].hex(),
"block_number": tx["blockNumber"],
"from": tx["from"],
"to": tx["to"],
"value": w3.fromWei(tx["value"], "ether"),
"gas": tx["gas"],
"gas_price": w3.fromWei(tx["gasPrice"], "gwei"),
}
for tx in block.transactions
]跑一次看看:
print(fetch_block_txs(18000000))4. 批量导出:按时间区间缓存为 CSV
实验总不能只取一个区块。下面方法支持 连续区间 自动下载,并实时展示进度:
import pandas as pd, os, tqdm
def export_range(start, end, out_dir='eth_txs'):
os.makedirs(out_dir, exist_ok=True)
for n in tqdm.tqdm(range(start, end+1), desc="抓取区块"):
df = pd.DataFrame(fetch_block_txs(n))
df.to_csv(f"{out_dir}/block_{n}.csv", index=False)
print("全部导出完成,数据已保存在", out_dir)调用:
# 抓取 18000200 ~ 18000210 共 11 个区块
export_range(18000200, 18000210)5. 进阶技巧:只保留特定合约或地址的交易
如果你只要研究 USDT 或某条 DeFi 协议,可在解析阶段就过滤:
TARGET = "0xdAC17F958D2ee523a2206206994597C13D831ec7".lower() # USDT 合约
def fetch_filtered(block_number, addr=TARGET):
records = fetch_block_txs(block_number)
return [tx for tx in records if (tx["to"] and tx["to"].lower() == addr)]6. 性能优化:循环阻塞式 → 并发异步
单机带宽和时间有限,推荐把 HTTP 请求改为 asyncio + aiohttp,实现 10 倍以上 提速。只需在原函数外加一层并发即可,完整代码放入附录,有需要点击下面链接查看。
FAQ:你最可能遇到的 5 个问题
问:免费节点有速率限制,如何判断自己被限流?
答:多线程短时间触发 429 或空响应就是信号,建议自备 Alchemy 或自建节点。
问:Infura 的免费额度够跑多少区块?
答:每天 10 万次调用,每个区块消耗 2 次,大约 5 万区块/天,约 7 天历史。
问:CSV 太多不好合并,有没有一键合并方案?
答:pandas.concat([pd.read_csv(f) for f in glob]) 一行搞定。
问:gasPrice 字段单位是 Gwei,如何与当前 GasNow 网站实时对比?
答:直接读取 w3.eth.gas_price 即可换算成 Gwei。
问:出现“replacement transaction underpriced”怎么办?
答:那是签名阶段才出现的链上错误,跟纯抓取脚本无关,放心跳过。
7. 漂移检测:实时验证数据完整性
抓取过程中,节点可能回滚,导致同一块号出现“孤块”。最简单的 漂移检测 逻辑:记录已保存的最大块号的 hash,若与节点再次请求的不一致,则重新抓取,保证 ETH 交易数据 的完整性。
8. 全盘可视化:三行代码做出交易量热力图
import matplotlib.pyplot as plt, seaborn as sns
df = pd.concat([pd.read_csv(f) for f in os.listdir('eth_txs') if f.endswith('.csv')])
sns.histplot(df['value'].astype(float), bins=50)
plt.title("交易量分布(区块 18,000,200–18,000,210)")
plt.show()实验结果可直接复制到研究报告中,方便非技术人员阅读。
9. 实战案例:如何通过 1000 万个区块回答 3 个商业问题
| 商业问题 | 字段与思路 |
|---|---|
| 每日 USDT 发行量 | 过滤 to == USDT 合约 且 input.startswith('0xa9059cbb') |
| 链上活跃地址数 | 对 from、to 做去重 |
| Gas 价格战高发时段 | 统计每区块平均 gasPrice 波动 |
10. 小结与下一步
通过 区块解析 + 交易记录导出 的组合拳,你已经拥有离线 ETH 交易数据 的完整链路。下一步可以从模型角度出发:
- 对价格波动构建机器学习特征;
- 结合链上 + 链下事件做多因子套利;
- 或贡献到开源社区,让更多人免费享用高质量数据。
研究路上,有数据就有无限可能。祝探索愉快!