PythonSPARQL查询怎么执行

wen python案例 4

本文目录导读:

PythonSPARQL查询怎么执行

  1. 使用SPARQLWrapper库(推荐)
  2. 使用RDFlib库
  3. 使用SPARQLWrapper查询本地端点(如Apache Jena Fuseki)
  4. 处理查询结果
  5. 错误处理和重试机制
  6. 常用公共SPARQL端点
  7. 安装依赖
  8. 完整示例:从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使用。

抱歉,评论功能暂时关闭!