在jupyter notebook中用API下载Materials Project中的数据

首先在电脑上打开powershell,输入

conda create -n mpcontribs_env python=3.11 -y

创建一个名为mpcontribs_env的新环境。然后输入

activate mpcontribs_env

激活这个环境。在这个环境中安装我们需要用到的库

pip install mpcontribs-client pandas openpyxl jupyterlab ipykernel

由于我之前已经在其他环境中安装过了jupyter notebook,所以我需要将这个环节加入jypyter内核

python -m ipykernel install --user --name mpcontribs_env --display-name "Python (MPContribs)"

接着输入jypyter notebook启动笔记本,新建一个python3的文件后,在kernel功能中找到change kernel,再找到Python (MPContribs),点击这个内核切换,成功之后右上角就应该从Python 3变成了Python (MPContribs)。

第二步:检查 Jupyter 环境

此时我们接着在单元格内输入


import sys
import os

print("Python executable:")
print(sys.executable)

print("Python version:")
print(sys.version)

确认输出的路径包含

...\envs\mpcontribs_env\python.exe

这样可以确认你使用的是新环境,而不是之前的其他环境。

第三步:获取 Materials Project API Key

打开:Materials Project Dashboard登录后进入 API Key 页面,复制你的 API Key。回到 Jupyter,建立第二个单元格:

from getpass import getpass

API_KEY = getpass("请输入 Materials Project API Key: ")

print("API Key 已读取")

运行后,Notebook 会出现密码输入框,输入的 Key 不会直接显示在屏幕上。这里需要自定义一个密码。

第四步:连接 Forbidden Transitions 项目

新建第三个单元格:


from mpcontribs.client import Client

# Forbidden Transitions 项目的名称
PROJECT = "ForbiddenTransitions"

# 创建客户端
client = Client(
    apikey=API_KEY,
    project=PROJECT
)

print("连接成功!")

# 获取项目基本信息
project_info = client.get_project()

print(project_info)

这里的forbidden_transitions是项目标识符,不是论文 DOI。

如果连接时报项目不存在,请回到MPContribs项目主页,查看浏览器地址栏中项目URL最后的名称,并将PROJECT修改为该名称。

运行成功后,应该能够看到项目名称、作者等信息。

第五步:下载数据

from pathlib import Path

# 下载目录
outdir = Path(r"C:\Users\HUAWEI\Desktop")
outdir.mkdir(parents=True, exist_ok=True)

# 下载全部 contribution
# 不传入 include=["tables"],因此不下载吸收光谱表格
downloaded = client.download_contributions(
    query={},
    outdir=outdir,
    overwrite=True
)

print("下载完成!")
print("文件数量:", len(downloaded))

for f in downloaded[:10]:
    print(f)

接着将其转换为csv格式

import pandas as pd
import json
import gzip
from pathlib import Path

# 使用之前下载好的全部材料记录
records = downloaded

print("材料总数:", len(records))
print("第一条记录字段:", records[0].keys())
print("第一条记录的 data:")
print(records[0].get("data"))


# 展开材料属性
def flatten_data(data, prefix="", result=None):

    if result is None:
        result = {}

    if not isinstance(data, dict):
        return result

    for key, value in data.items():

        new_key = f"{prefix}.{key}" if prefix else key

        if isinstance(value, dict):

            # MPContribs 数值字段
            if "value" in value:
                result[new_key] = value["value"]

                if value.get("unit") is not None:
                    result[new_key + "_unit"] = value["unit"]

            elif "display" in value and len(value) <= 4:
                result[new_key] = value["display"]

            else:
                flatten_data(value, new_key, result)

        else:
            result[new_key] = value

    return result


# 转换成表格
rows = []

for record in records:

    row = {
        "MP_ID": record.get("identifier"),
        "Formula": record.get("formula")
    }

    row.update(
        flatten_data(record.get("data") or {})
    )

    rows.append(row)


df = pd.DataFrame(rows)

# 保存文件
outdir = Path(r"C:\Users\HUAWEI\Desktop")
outdir.mkdir(parents=True, exist_ok=True)

# 完整原始数据备份
with gzip.open(
    outdir / "ForbiddenTransitions_raw.json.gz",
    "wt",
    encoding="utf-8"
) as f:
    json.dump(records, f, ensure_ascii=False, default=str)

# 展平后的 Excel 兼容 CSV
df.to_csv(
    outdir / "ForbiddenTransitions_all_properties.csv",
    index=False,
    encoding="utf-8-sig"
)

print("\n下载和整理完成!")
print("材料记录数:", df.shape[0])
print("属性字段数:", df.shape[1])
print("有科学属性的材料数:",
      sum(bool(r.get("data")) for r in records))

print("\n所有字段:")
print(df.columns.tolist())

display(df.head(10))

这样就获得了18634种材料的性质。

posted @ 2026-10-31 11:15  欢腾嘻嘻  阅读(5)  评论(0)    收藏  举报