如何在OpenRefine中通过Wikidata API提取实体的“实例类型”等属性?
在OpenRefine中调用Wikidata API提取实体属性(实例类型等)
1. 构造Wikidata API查询URL
Wikidata的wbgetentities接口可直接根据实体ID获取属性数据,核心参数如下:
action=wbgetentities:指定API操作类型ids=实体ID:传入你的Wikidata实体ID(如Q42),支持多个ID用竖线|分隔批量查询props=claims|labels:claims获取属性声明,labels获取实体标签(可选,用于直接显示名称而非ID)format=json:指定返回JSON格式languages=zh:指定返回中文标签(可选,可替换为其他语言代码)
单个实体查询URL示例:
https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q42&props=claims|labels&format=json&languages=zh
批量查询示例(同时查Q42和Q215380):
https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q42|Q215380&props=claims|labels&format=json&languages=zh
2. 在OpenRefine中获取API数据
假设你的实体ID存储在名为wikidata_id的列中:
- 选中该列,点击下拉菜单 → 编辑列 → 添加列-从URL获取
- 在「URL表达式」中输入GREL代码,动态生成每个实体的查询URL:
"https://www.wikidata.org/w/api.php?action=wbgetentities&ids=" + value + "&props=claims|labels&format=json&languages=zh" - 设置请求延迟(建议1-2秒,避免触发API限流),点击「确定」运行,生成包含JSON数据的新列(命名为
wikidata_data)。
3. 解析JSON提取目标属性
提取实例类型(P31)
实例类型对应Wikidata属性P31(比如Q5=人物、Q215380=乐队),添加新列,使用以下GREL表达式提取中文标签:
var entity = value.parseJson().entities[value.parseJson().entities.keys()[0]]; if (entity.claims.P31) { forEach(entity.claims.P31, v, var typeId = v.mainsnak.datavalue.value.id; entity.labels[typeId] ? entity.labels[typeId].value : typeId ).join("; ") } else { "" }
如果只需要实例类型的ID,简化为:
forEach(value.parseJson().entities[value.parseJson().entities.keys()[0]].claims.P31, v, v.mainsnak.datavalue.value.id).join("; ")
提取其他属性
以提取人物出生日期(P569,YYYY-MM-DD格式)为例,添加新列使用:
var entity = value.parseJson().entities[value.parseJson().entities.keys()[0]]; entity.claims.P569 ? entity.claims.P569[0].mainsnak.datavalue.value.time.substring(1,11) : ""
替换P569为其他属性ID即可提取对应数据(比如乐队成立日期用P571,国籍用P27)。
4. 注意事项
- Wikidata API对请求频率有限制,批量处理时务必设置合理延迟,或使用批量ID查询减少请求次数
- 部分实体可能没有目标属性,需用
if判断避免报错 - 若需要更复杂的查询(如过滤属性值),可改用Wikidata Query Service(SPARQL),通过
sparql接口调用查询结果
内容的提问来源于stack exchange,提问作者Norhther
相关产品推荐
相关产品推荐

