从Wikidata中提取RDF三元组

2024-10-02 20:35:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我遵循this关于从Wikidata查询的指南

我可以通过以下方式获得某个实体(如果我知道其代码):

from wikidata.client import Client
client = Client()
entity = client.get('Q20145', load=True)
entity
>>><wikidata.entity.Entity Q20145 'IU'>
entity.description
>>>m'South Korean singer-songwriter, record producer, and actress'

但是我怎样才能得到该实体的RDF三元组呢?也就是说,所有以(主语、谓语、宾语)形式输出和输入的边

看起来像是this,所以问题设法得到了三元组,但只从数据转储here中得到。我正试图从图书馆自己那里得到它


Tags: 代码fromimport实体clientget方式指南
2条回答

But how can I get the RDF triples of that entity?

通过使用SPARQL DESCRIBE查询(source),您可以得到一个单一的结果RDF图,其中包含(主语、谓语、宾语)形式的所有传出和传入边。这可以使用以下Python示例代码(source)实现:

from SPARQLWrapper import SPARQLWrapper

queryString = """DESCRIBE wd:Q20145"""
sparql = SPARQLWrapper("https://query.wikidata.org/sparql")

sparql.setQuery(queryString)
sparql.setReturnFormat(JSON)
results = sparql.query().convert()

for result in results["results"]["bindings"]:
    print(result)

如果只想获取传出边,请使用CONSTRUCT {?s ?p ?o} WHERE {BIND(wd:Q20145 AS ?s) ?s ?p ?o},对于传入边,请使用CONSTRUCT {?s ?p ?o} WHERE {BIND(wd:Q20145 AS ?o) ?s ?p ?o}(感谢@ 未提供信息的用户)

示例代码:

from SPARQLWrapper import SPARQLWrapper

queryString = """CONSTRUCT {?s ?p ?o} WHERE {BIND(wd:Q20145 AS ?s) ?s ?p ?o}"""
sparql = SPARQLWrapper("https://query.wikidata.org/sparql")

sparql.setQuery(queryString)
sparql.setReturnFormat(JSON)
results = sparql.query().convert()

for result in results["results"]["bindings"]:
    print(result)

DESCRIBECONSTRUCT得到的结果可以分别看到herehere

如果只需要输出边,可以通过调用https://www.wikidata.org/wiki/Special:EntityData/Q20145.nt直接检索它们

from rdflib import Graph
g = Graph()
g.parse('https://www.wikidata.org/wiki/Special:EntityData/Q20145.nt', format="nt")    
for subj, pred, obj in g:
    print(subj, pred, obj)

要获取传入和传出边缘,需要查询数据库。在Wikidata上,这是使用Wikidata Query Service和查询langauge SPARQL完成的。获取所有边的SPARQL表达式非常简单,如DESCRIBE wd:Q20145

使用Python,您可以使用以下代码检索查询结果:

import requests
import json

endpoint_url = "https://query.wikidata.org/sparql"
headers = { 'User-Agent': 'MyBot' }
payload = {
    'query': 'DESCRIBE wd:Q20145',
    'format': 'json'
}
r = requests.get(endpoint_url, params=payload, headers=headers)
results = r.json()

triples = []
for result in results["results"]["bindings"]:   
    triples.append((result["subject"], result["predicate"], result["object"]))
print(triples)

这为您提供了复杂基础数据模型的完整结果来源。如果要分别查询传入边和传出边,请写入DESCRIBE wd:Q20145而不是CONSTRUCT {?s ?p ?o} WHERE {BIND(wd:Q20145 AS ?s) ?s ?p ?o}以仅具有传出边或CONSTRUCT {?s ?p ?o} WHERE {BIND(wd:Q20145 AS ?o) ?s ?p ?o}以仅具有传入边

根据您的目标,您可能希望过滤掉一些三元组,例如语句三元组,并且您可能希望简化一些三元组。 获得更清晰结果的一种可能性是将最后四行替换为:

triples = []
for result in results["results"]["bindings"]:   
    subject = result["subject"]["value"].replace('http://www.wikidata.org/entity/', '')
    object = result["object"]["value"].replace('http://www.wikidata.org/entity/', '')
    predicate = result["predicate"]["value"].replace('http://www.wikidata.org/prop/direct/', '')
    if 'statement/' in subject or 'statement/' in object:
        continue
    triples.append((subject, predicate, object))
print(triples)

相关问题 更多 >