本文目录导读:

- 使用SPARQLWrapper库(推荐)
- 使用RDFlib库
- 使用SPARQLWrapper查询本地端点(如Apache Jena Fuseki)
- 处理查询结果
- 错误处理和重试机制
- 常用公共SPARQL端点
- 安装依赖
- 完整示例:从Wikidata查询数据
在Python中执行SPARQL查询,主要有以下几种主流方法:
使用SPARQLWrapper库(推荐)
这是最常用的Python SPARQL客户端库:
from SPARQLWrapper import SPARQLWrapper, JSON
# 创建SPARQL端点连接
sparql = SPARQLWrapper("https://query.wikidata.org/sparql") # 示例:Wikidata端点
# 设置查询
sparql.setQuery("""
SELECT ?item ?itemLabel
WHERE {
?item wdt:P31 wd:Q5. # 人类实例
?item wdt:P19 wd:Q64. # 出生在柏林
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 10
""")
# 设置返回格式
sparql.setReturnFormat(JSON)
# 执行查询并获取结果
results = sparql.query().convert()
# 处理结果
for result in results["results"]["bindings"]:
print(result["item"]["value"], result["itemLabel"]["value"])
使用RDFlib库
RDFlib功能更全面,支持查询和操作RDF数据:
from rdflib import Graph, URIRef, Literal
from rdflib.plugins.sparql import prepareQuery
# 从URL加载RDF数据
g = Graph()
g.parse("https://www.w3.org/People/Berners-Lee/card")
# 或者从本地文件加载
# g.parse("data.rdf")
# 准备SPARQL查询
q = prepareQuery("""
SELECT ?name ?email
WHERE {
?person foaf:name ?name .
OPTIONAL { ?person foaf:mbox ?email }
}
""", initNs={"foaf": "http://xmlns.com/foaf/0.1/"})
# 执行查询
for row in g.query(q):
print(f"Name: {row.name}, Email: {row.email}")
使用SPARQLWrapper查询本地端点(如Apache Jena Fuseki)
from SPARQLWrapper import SPARQLWrapper, JSON
# 本地SPARQL端点
sparql = SPARQLWrapper("http://localhost:3030/dataset/sparql")
sparql.setQuery("""
PREFIX ex: <http://example.org/>
SELECT ?subject ?predicate ?object
WHERE {
?subject ?predicate ?object
}
LIMIT 20
""")
sparql.setReturnFormat(JSON)
results = sparql.query().convert()
for result in results["results"]["bindings"]:
subj = result["subject"]["value"]
pred = result["predicate"]["value"]
obj = result["object"]["value"]
print(f"{subj} - {pred} - {obj}")
处理查询结果
处理JSON格式的结果:
def process_results(results):
"""处理SPARQL查询结果"""
bindings = results["results"]["bindings"]
# 转换为更易用的格式
processed = []
for binding in bindings:
row = {}
for var, value in binding.items():
row[var] = {
"value": value["value"],
"type": value.get("type", "unknown"),
"datatype": value.get("datatype", None),
"language": value.get("xml:lang", None)
}
processed.append(row)
return processed
# 使用示例
results = sparql.query().convert()
data = process_results(results)
for row in data:
print(row)
错误处理和重试机制
import time
from SPARQLWrapper import SPARQLWrapper, JSON
from urllib.error import HTTPError
def execute_sparql_with_retry(endpoint, query, max_retries=3):
"""带重试机制的SPARQL查询执行"""
sparql = SPARQLWrapper(endpoint)
sparql.setQuery(query)
sparql.setReturnFormat(JSON)
for attempt in range(max_retries):
try:
results = sparql.query().convert()
return results
except HTTPError as e:
if e.code == 429: # 请求过多
wait_time = 2 ** attempt
print(f"速率限制,等待{wait_time}秒...")
time.sleep(wait_time)
else:
raise
except Exception as e:
if attempt == max_retries - 1:
raise
time.sleep(1)
return None
# 使用示例
endpoint = "https://query.wikidata.org/sparql"
query = """
SELECT * WHERE {
?s ?p ?o
} LIMIT 5
"""
results = execute_sparql_with_retry(endpoint, query)
常用公共SPARQL端点
# 一些常用的公共SPARQL端点
ENDPOINTS = {
"wikidata": "https://query.wikidata.org/sparql",
"dbpedia": "https://dbpedia.org/sparql",
"europeana": "https://api.europeana.eu/sparql",
"geonames": "https://geonames-semantic-web.appspot.com/sparql",
"culturalevents": "https://cultural-events.org/sparql"
}
安装依赖
# 安装SPARQLWrapper pip install SPARQLWrapper # 安装RDFlib pip install rdflib
完整示例:从Wikidata查询数据
from SPARQLWrapper import SPARQLWrapper, JSON
import json
def query_wikidata_cities():
"""查询德国主要城市"""
endpoint = "https://query.wikidata.org/sparql"
query = """
SELECT ?city ?cityLabel ?population
WHERE {
?city wdt:P31 wd:Q15284; # 城市或城镇实例
wdt:P17 wd:Q183; # 在德国
wdt:P1082 ?population. # 人口数量
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)
LIMIT 20
"""
sparql = SPARQLWrapper(endpoint)
sparql.setQuery(query)
sparql.setReturnFormat(JSON)
results = sparql.query().convert()
print("德国主要城市及人口:")
print("-" * 50)
for result in results["results"]["bindings"]:
city = result.get("cityLabel", {}).get("value", "Unknown")
population = result.get("population", {}).get("value", "Unknown")
print(f"{city}: {population}")
# 执行查询
query_wikidata_cities()
推荐使用SPARQLWrapper,它最简洁易用,且支持各种SPARQL端点,如果需要本地处理RDF数据,可以结合RDFlib使用。