Python Wikidata-获取大量ID的标签
我在ndjson文件中有一个大约300000个wikidata ID(例如Q1347065、Q731635等)的列表,如下所示Python Wikidata-获取大量ID的标签,python,wikidata,ndjson,Python,Wikidata,Ndjson,我在ndjson文件中有一个大约300000个wikidata ID(例如Q1347065、Q731635等)的列表,如下所示 {"Q1347065": ""} {"Q731635": ""} {"Q191789": ""} ... etc 我希望得到每个id的标签,并形成键值字典,例如 {“Q1347065”:“会厌炎”、“Q731635”:“弗农山”…}等 在ID列表变得
{"Q1347065": ""}
{"Q731635": ""}
{"Q191789": ""} ... etc
我希望得到每个id的标签,并形成键值字典,例如
{“Q1347065”:“会厌炎”、“Q731635”:“弗农山”…}
等
在ID列表变得如此庞大之前,我使用的是Wikidata python库()
但速度太慢(1000个ID大约需要15个小时)。有没有比我现在做的更快的方法来实现这一点呢?在回答之前:我不知道你说的json是什么意思;我假设您想要
json.dump(l,out)
我的答案在于使用以下SPARQL查询:
用于同时询问多个标签
这大大加快了执行时间,因为瓶颈是连接的数量,使用这种方法,id->label映射完全在服务器端完成
import json
import ndjson
import re
import requests
def wikidata_query(query):
url = 'https://query.wikidata.org/sparql'
try:
r = requests.get(url, params = {'format': 'json', 'query': query})
return r.json()['results']['bindings']
except json.JSONDecodeError as e:
raise Exception('Invalid query')
with open("claims.ndjson") as f, open('claims_to_strings.json', 'w') as out:
claims = ndjson.load(f)
l = {}
for d in claims:
l.update(d)
item_ids = l.keys()
sparql_values = list(map(lambda id: "wd:" + id, item_ids))
item2label = wikidata_query('''
SELECT ?item ?itemLabel WHERE {
VALUES ?item { %s }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}''' % " ".join(sparql_values))
for result in item2label :
item = re.sub(r".*[#/\\]", "", result['item']['value'])
label = result['itemLabel']['value']
l[item] = label
json.dump(l, out)
我猜您无法对所有300000个项目进行一次查询,但您可以轻松找到受支持的最大接受id数,并根据该数字拆分原始id列表。是的,我是说l而不是r,谢谢您的关注,谢谢您的建议!我现在就去试试@Paschalis正常,但还要检查
转储
和转储
方法之间的差异!
SELECT ?item ?itemLabel WHERE {
VALUES ?item { wd:Q1347065 wd:Q731635 wd:Q105492052 }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
import json
import ndjson
import re
import requests
def wikidata_query(query):
url = 'https://query.wikidata.org/sparql'
try:
r = requests.get(url, params = {'format': 'json', 'query': query})
return r.json()['results']['bindings']
except json.JSONDecodeError as e:
raise Exception('Invalid query')
with open("claims.ndjson") as f, open('claims_to_strings.json', 'w') as out:
claims = ndjson.load(f)
l = {}
for d in claims:
l.update(d)
item_ids = l.keys()
sparql_values = list(map(lambda id: "wd:" + id, item_ids))
item2label = wikidata_query('''
SELECT ?item ?itemLabel WHERE {
VALUES ?item { %s }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}''' % " ".join(sparql_values))
for result in item2label :
item = re.sub(r".*[#/\\]", "", result['item']['value'])
label = result['itemLabel']['value']
l[item] = label
json.dump(l, out)