N:::만지작 거리기
N_19. SPARQLWrapper로 SPARQL Endpoint 사용하기
joyHong
2021. 9. 10. 00:39
SPARQL Endpoint를 제공하는 곳이 있으면 SPARQL 을 통해 원하는 데이터를 웹상에서 가져올 수 있다.
이전 내용(https://joyhong.tistory.com/144) 에서는 Fuseki를 활용하여 간단하게 SPARQL Endpoint를 구성해 보았는데
로컬에 SPARQL Endpoint를 구성하고 여기에 질의를 해보는 내용을 기술하였다.
사용하는 라이브러리는 SPARQLWrapper와 RDFLib 이다.
04.QueryToSPARQLEndpoint
SPARQL Endpoint에 질의하기
SPARQL Endpoint를 제공하면 웹상에서 자유롭게 질의를 하여 결과를 받아 올 수 있다.
이 전에 Fuseki를 활용하여 간단하게 SPARQL Endpoint를 구축하였는데, 이를 활용하여 테스트를 진행한다.
다양한 형태의 SPARQL을 구성하고 여러가지 포맷으로 결과를 받아온다.
- 사용하는 라이브러리
RDFLib
(https://rdflib.readthedocs.io/en/5.0.0/index.html)SPARQLWrapper
(https://rdflib.dev/sparqlwrapper/doc/1.8.5/main.html)
작성자 : 허홍수
e-mail : su4620@gmail.com
blog : http://joyhong.tistory.com
e-mail : su4620@gmail.com
blog : http://joyhong.tistory.com
SPARQL 실행¶
기본적으로 SPARQL 실행 후 결과 리턴 포맷은 XML이기 때문에 별다른 설정을 하지 않으면 XML 포맷으로 결과값이 넘어온다.
아래 예시들에서는 디폴트인 XML을 그대로 사용하고 있다.
SELECT¶
In [1]:
from SPARQLWrapper import SPARQLWrapper
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT *
WHERE {
?s ?p ?o
} LIMIT 10
""")
results = sparql.query().convert()
# convert()가 자동으로 결과를 변환시킨다. 리턴이 xml이기 때문에 xml.dom.minidom 형태로 바꾸어준다.
print(results.toxml())
ASK¶
In [2]:
from SPARQLWrapper import SPARQLWrapper
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
ASK WHERE {
<http://joyhong.tistory.com/resource/h_1> ?p ?label
}
""")
results = sparql.query().convert()
print(bool(results))
CONSTRUCT¶
CONSTRUCT와 DESCRIBE RDF/XML 구문으로 리턴된다.
In [3]:
from SPARQLWrapper import SPARQLWrapper
from rdflib import Graph
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
CONSTRUCT {
?s ?p ?o.
} WHERE {
?s ?p ?o .
FILTER(?s=<http://joyhong.tistory.com/resource/h_1>)
}
""")
results = sparql.query().convert()
# CONSTRUCT 구문은 RDF/XML 형태로 리턴이 되기 때문에 convert()가 자동으로 Graph 인스턴스로 변환시킨다.
# 따라서 results는 타입이 Graph 임으로 바로 serialize() 를 통해 직렬화가 가능하다.
print(results.serialize().decode('utf-8'))
DESCRIBE¶
In [4]:
from SPARQLWrapper import SPARQLWrapper
from rdflib import Graph
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
DESCRIBE <http://joyhong.tistory.com/resource/h_16>
""")
results = sparql.query().convert()
# DESCRIBE 구문은 CONSTRUCT와 마찬가지로 RDF/XML 형태로 리턴이 되기 때문에 convert()가 자동으로 Graph 인스턴스로 변환시킨다.
# 따라서 results는 타입이 Graph 임으로 바로 serialize() 를 통해 직렬화가 가능하다.
print(results.serialize().decode('utf-8'))
Graph 리턴인 경우 여러가지 직렬화¶
CONSTRUCT와 DESCRIBE 구문은 RDF/XML 형태로 리턴이 되고, convert()를 통해 Graph의 인스턴스로 변환되기 때문에 여러가지 직렬화를 사용할 수 있다.
RDF/XML¶
In [5]:
from SPARQLWrapper import SPARQLWrapper
from rdflib import Graph
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
DESCRIBE <http://joyhong.tistory.com/resource/h_16>
""")
results = sparql.query().convert()
print('XML(디폴트) 형태로 출력')
print('='*100)
print(results.serialize().decode('utf-8'))
Turtle¶
In [6]:
print('TURTLE 형태로 출력')
print('='*100)
print(results.serialize(format='turtle').decode('utf-8'))
JSON-LD¶
In [7]:
print('JSON-LD 형태로 출력')
print('='*100)
print(results.serialize(format='json-ld').decode('utf-8'))
N-Triples¶
In [8]:
print('N-Triples 형태로 출력')
print('='*100)
print(results.serialize(format='nt').decode('utf-8'))
반환 포맷 설정¶
SELECT 구문¶
중요! SELECT와 ASK 구문은 XML, JSON, CSV/TSV 형태로만 결과를 반환한다.
JSON 형태로 결과 반환¶
In [9]:
from SPARQLWrapper import SPARQLWrapper, JSON
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT *
WHERE {
?s ?p ?o .
} LIMIT 10
""")
sparql.setReturnFormat(JSON)
results = sparql.query().convert()
# JSON 형태로 결과를 받으면 convert()가 자동으로 dictionary 변환하기 때문에 아래와 같이 결과를 확인할 수 있다.
for result in results["results"]["bindings"]:
print(result["p"]["value"], "\t", result["o"]["value"])
CSV 형태로 결과 반환¶
In [10]:
from SPARQLWrapper import SPARQLWrapper, CSV
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT *
WHERE {
?s ?p ?o .
} LIMIT 10
""")
sparql.setReturnFormat(CSV)
results = sparql.query().convert()
# CSV 형태로 결과를 받으면 convert()가 자동으로 string으로 변환하기 때문에 아래와 같이 결과를 확인할 수 있다.
print(results.decode('utf-8'))
DESCRIBE 구문¶
중요! DESCRIBE와 CONSTRUCT 구문은 RDF/XML 혹은 그와 동일한 그래프 형태로만 결과를 반환한다.
Turtle 형태로 결과 반환¶
In [11]:
from SPARQLWrapper import SPARQLWrapper, TURTLE
from rdflib import Graph
sparql = SPARQLWrapper("http://localhost:3030/publicdata/query")
sparql.setQuery("""
DESCRIBE <http://joyhong.tistory.com/resource/h_16>
""")
sparql.setReturnFormat(TURTLE)
sparql.setOnlyConneg(True)
results = sparql.query().convert()
print('='*100)
print('string 형태의 결과')
print('='*100)
print(results.decode('utf-8'))
print('='*100)
print('turtle 직렬화 결과')
print('='*100)
# results는 string 으로 변환된 상태 이기 때문에 이를 Graph에 담아야 한다.
g = Graph()
g.parse(data=results, format="turtle")
print(g.serialize(format='turtle').decode('utf-8'))
Finish !!