 | Nível: Intermediário Bob DuCharme, VP of Corporate Documentation, UDICo
21/Jul/2009 Ao fornecer acesso aberto a quantidades crescentes de Dados Vinculados, terminais SPARQL públicos estão impulsionando o crescimento da Web Semântica fornecendo dados excelentes para que você use em seus aplicativos. Como com muito outros Web sites acionados por dados por aí, é possível criar uma página da Web enviando uma consulta a esses terminais e, então, agrupar os resultados em tags HTML; a grande diferença para terminais SPARQL é a disponibilidade pública desses novos dados para seus aplicativos. Este artigo mostra como o script CGI simples pode obter dados de dois terminais SPARQL diferentes para construir aplicativos que respondem suas perguntas de usuários sobre atores compartilhadas entre dois diretores e quais músicos lançaram quais discos.
 |
Acrônimos Usados Frequentemente
- CSS: Cascading stylesheet
- CGI: Interface Gateway Comum
- HTML: Linguagem de Marcação de Hipertexto
- HTTP: Protocolo de Transporte de Hipertexto
- JSON: JavaScript Object Notation
- RDBMS: Sistema de Gerenciamento de Banco de Dados Relacional
- RDF: Resource Description Framework
- REST: Representational State Transfer
- SPARQL: SPARQL Protocol and RDF Query Language
- URI: Identificador Uniforme de Recursos
- URL: Localizador Uniforme de Recursos
- XML: Linguagem de Marcação Extensível
|
|
Terminais SPARQL fornecem acesso a bancos de dados através de consultas que usam a linguagem de consulta SPARQL padrão. Cada vez mais desses dados estão sendo disponibilizados na Internet pública e seus aplicativos podem recuperar e usar esses dados de forma bem semelhante que fazem com dados do banco de dados relacional. Quando conhecer um pouco de SPARQL, é possível incorporar consultas nessa linguagem em aplicativos que são, do contrário, muito semelhantes a aplicativos já gravados, mas você (e, após gravar esses aplicativos, seus usuários) terá acesso a todos os tipos de novos dados.
Este artigo discute dois exemplos de aplicativos que exibem formulários fáceis e simples, consultam o terminal SPARQL de um banco de dados e apresentam os resultados sem exigir que o usuário do formulário tenha qualquer conhecimento sobre a tecnologia e os padrões usados para fornecer esses dados.
Para obter um arquivo zip que acompanha o artigo que inclui todos os arquivos de exemplo, consulte Download. O primeiro aplicativo permite que você dê o nome de dois diretores de filmes e, então, recupera os nomes dos atores que aparecem em filmes de ambos; o segundo recupera informações sobre discos de artistas gravados.
Como com tantos Web sites acionados por dados por aí, a arquitetura básica desses aplicativos segue este padrão:
- O usuário insere um ou mais termos de consulta em um formulário da Web e clica em Enviar.
- O formulário passa os valores inseridos para um script CGI.
- O script CGI conecta os valores a uma consulta e envia a consulta a um servidor de banco de dados.
- O servidor retorna os resultados da consulta para o script CGI, que constrói uma página HTML em torno dos dados retornados e envia a página ao navegador do usuário.
Esse padrão é tão antigo quanto os scripts CGI. O que o torna novo, desta vez, é que a linguagem de consulta em uso é SPARQL, em vez da mais conhecida SQL. O que é interessante é que enquanto poucos, se algum banco de dados SQL, estão disponíveis na Internet para que seu aplicativo consulte livremente, mais bancos de dados grandes e úteis estão sendo disponibilizados com interfaces SPARQL (também conhecida como terminais SPARQL) o tempo todo. Na verdade, esses terminais
SPARQL são, frequentemente, interfaces adicionais incluídas em bancos de dados relacionais.
Além dos terminais SPARQL que aparecem na Internet pública, outros estão aparecendo por trás de firewalls para facilitar consulta entre silos de dados corporativos.
Aplicativo Um: O Banco de Dados e a Consulta
Se o primeiro aplicativo automatizar a entrega de uma consulta a um banco de dados específico e a formatação dos dados retornados, vamos iniciar com seu banco de dados e consulta.
Enquanto o
Internet Movie Database (IMDb) pode informar muitas coisas sobre praticamente qualquer filme de áudio no idioma inglês, não aceitará consultas que permitam a comparação e o contraste de informações. Por exemplo, se eu quiser saber se algum ator apareceu em um filme dirigido por Sofia Coppola e outro dirigido por seu pai, Francis Ford Coppola, precisaria ir às seis páginas da Web do IMDb de filmes que ela dirigiu e às 32 páginas de filmes que ele dirigiu, compilar manualmente uma lista de atores e, então, cruzar as referências.
Felizmente, o Linked Movie Database em
linkedmdb.org fornece um banco de dados de informações de créditos de filmes que aceita consultas SPARQL.
Por exemplo, a consulta na Lista 1 indica que deve listar os títulos de todos os filmes dirigidos por Sofia Coppola:
Lista 1. Uma Consulta de Filmes de Sofia Coppola
PREFIX m: <http://data.linkedmdb.org/resource/movie/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?filmTitle WHERE {
?film rdfs:label ?filmTitle.
?film m:director ?dir.
?dir m:director_name "Sofia Coppola".
}
|
SPARQL é projetado para consultar dados representados com o modelo de dados RDF, que representa dados como uma coleta de triplos, cada um dos quais tendo um sujeito, um predicado e um objeto. Às vezes, é mais fácil pensar neles como entidades, nome de atributo, atributo e valor. Um desses triplos poderia ser descrito como "a entidade com o ID http://data.linkedmdb.org/resource/director/7764 possui um valor de director_name igual a 'Sofia Coppola'".
Em SPARQL, variáveis são iniciadas com pontos de interrogação e essa consulta usa triplos com variáveis inseridas em determinados locais para descrever três condições para os títulos de filmes que deseja que sejam retornados:
- RDF usa URIs como identificadores, mas deseja que o banco de dados recupere títulos de filmes legíveis por seres humanos. Na consulta, a variável
?film fica no lugar do identificador URI do filme. O file possui um rdfs:label de ?filmTitle, que é o que a consulta pergunta na instrução SELECT. O predicado rdfs:label é definido no padrão Esquema de RDF e a declaração de espaço de nomes na segunda linha da consulta esclarece exatamente a o que o prefixo rdfs se refere.
- O filme tem um diretor com o identificador
?dir.
- Como
?dir fica no lugar de um identificador URI para um diretor e você deseja o nome real do diretor, a consulta solicita
?dir , cujo valor m:director_name é Sofia Coppola. Outra declaração de espaço de nomes no início da consulta mostra a que o prefixo
m se refere. Eu sabia que director_name era o nome de predicado correto a ser usado, pois consultei os nomes que os dados de linkedmdb.org usaram antes de gravar essa consulta, assim como verifico os que um esquema XML ou RDBMS usa antes de criar uma consulta XQuery ou SQL. É possível descobrir isso a partir de qualquer terminal SPARQL que diz essencialmente: "mostre-me todos os predicados usados em quaisquer triplos, mas sem repetições":
SELECT DISTINCT ?p WHERE {?s ?p ?o} |
Muitos terminais SPARQL, incluindo aquele em linkedmdb.org, oferecem uma interface baseada em formulário para que você experimente consultas SPARQL.
Se for para o formulário SNORQL dos mesmos, cole uma das duas consultas acima e clique em
Ir!, deverá ver uma lista dos filmes de Sofia Coppola.
(Se a configuração Resultados: padrão não funcionar, tente outras, principalmente como JSON, o formato que será usado em seu aplicativo.)
A Lista 2 mostra outra consulta para experimentar no formulário SNORQL de linkedmdb.org. Esta lista todos os atores em todos os filmes de Sofia Coppola:
Lista 2. Uma Consulta para Recuperar Atores
PREFIX m: <http://data.linkedmdb.org/resource/movie/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?actorName ?filmTitle WHERE {
?film rdfs:label ?filmTitle;
m:director ?dir;
m:actor ?actor.
?dir m:director_name "Sofia Coppola".
?actor m:actor_name ?actorName.
}
|
Além de solicitar os títulos dos filmes, solicita os atores de cada filme
—ou seja, os nomes dos atores que acompanham os identificadores dos atores associados a cada filme, pois, como em sua primeira consulta (e na maioria das consultas
SPARQL), URIs são usados para identificar quais dados são desejados, mas, depois, obtêm os rótulos legíveis por seres humanos associados aos URIs para a saída. É semelhante a como uma consulta SQL pode usar valores de ID do produto para cruzar referências de produtos e, então, obter nomes de produtos para o relatórios em si.
Essa consulta também introduz algum SPARQL abreviado. Em vez de esclarecer três triplos integrais para indicar que deseja os dados de título, diretor e ator associados a cada filme, usa ponto e vírgula para mostrar que os pares predicado/objeto
m:director ?dir e m:actor ?actor vão junto com o sujeito ?film, assim como o par predicado/objeto rdfs:label ?filmTitle .
Construindo o Aplicativo
O propósito do primeiro aplicativo é fornecer os benefícios do banco de dados de linkedmdb.org e a linguagem de consulta SPARQL enquanto a consulta real e o URI são ocultados do usuário do aplicativo.
Em termos de arquitetura do sistema descrito acima,
O usuário do aplicativo insere dois nomes de diretores usando o formulário da Figura 1.
Figura 1. Formulário de Entrada para o Aplicativo commonActors
- O formulário passa os dois nomes de diretores para o script CGI commonActors.cgi.
- O script CGI conecta os nomes de diretores a uma consulta SPARQL e envia a consulta ao terminal SPARQL de linkedmdb.org em http://data.linkedmdb.org/sparql.
- O terminal SPARQL retorna uma versão JSON dos resultados e o script CGI constróis uma página HTML em torno dos dado retornados e envia a página ao navegador do usuário.
A Lista 3 mostra a consulta SPARQL que será enviada codificada permanentemente para perguntar sobre Sofia e Francis Ford Coppola:
Lista 3. Consulta SPARQL para Listar Atores Comuns em Filmes de Sofia e Francis Ford Coppola
PREFIX m: <http://data.linkedmdb.org/resource/movie/>
SELECT DISTINCT ?actorName WHERE {
?dir1 m:director_name "Sofia Coppola".
?dir2 m:director_name "Francis Ford Coppola".
?dir1film m:director ?dir1;
m:actor ?actor.
?dir2film m:director ?dir2;
m:actor ?actor.
?actor m:actor_name ?actorName.
}
|
Se colar essa consulta na interface SNORQL de linkedmdb.org, verá que somente Kathleen Turner esteve em um filme dirigido por cada um dos dois Coppolas.
O formulário de entrada da Web armazenado no arquivo commonActors.html (que você mesmo pode experimentar em http://www.snee.com/sparqlforms/commonActors.html) designa os nomes dos diretores inseridos às variáveis dir1 e dir2, que passa para o script commonActors.cgi.
Lista 4. Formulário de Entrada da Web para o Aplicativo commonActors
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Find common actors between two directors</title>
<link href="simple.css" type="text/css" rel="stylesheet" />
</head>
<body>
<h1>Find common actors between two directors</h1>
<form action="commonActors.cgi" method="get">
<p>Enter the "official" name of each director (check
<a href="http://www.imdb.com">IMDB</a> if you're not sure)
and click "Search" to list actors who have appeared in movies by
both directors.</p>
<p>
<input type="text" name="dir1"/>
<input type="text" name="dir2"/>
<input type="submit" value="search"/>
</p>
</form>
</body>
</html>
|
Uma boa coisa sobre os terminais SPARQL é que é possível se comunicar com todos eles usando uma interface HTTP baseada em REST, mas uma procura da Web deve fornecer uma interface ainda mais simples padronizada para sua linguagem de programação favorita. Gravei meu script CGI commonActors.cgi em Python e usei a biblioteca SPARQLWrapper para simplificar o envio de minha consulta e a descompactação dos resultados.
Lista 5. Script Python para o Aplicativo commonActors
#!/usr/local/bin/python
import sys
sys.path.append('/usr/home/bobd/lib/python/') # needed for hosted version
from SPARQLWrapper import SPARQLWrapper, JSON
import string
import urllib
import cgi
def main():
form = cgi.FieldStorage()
dir1name = form.getvalue('dir1')
dir2name = form.getvalue('dir2')
sparql = SPARQLWrapper("http://data.linkedmdb.org/sparql")
queryString = """
PREFIX m: <http://data.linkedmdb.org/resource/movie/>
SELECT DISTINCT ?actorName WHERE {
?dir1 m:director_name "DIR1-NAME".
?dir2 m:director_name "DIR2-NAME".
?dir1film m:director ?dir1;
m:actor ?actor.
?dir2film m:director ?dir2;
m:actor ?actor.
?actor m:actor_name ?actorName.
}
"""
queryString = queryString.replace("DIR1-NAME",dir1name)
queryString = queryString.replace("DIR2-NAME",dir2name)
sparql.setQuery(queryString)
sparql.setReturnFormat(JSON)
try:
ret = sparql.query()
results = ret.convert()
requestGood = True
except Exception, e:
results = str(e)
requestGood = False
print """Content-type: text/html
<html>
<head>
<title>results</title>
<link href="simple.css" type="text/css" rel="stylesheet" />
</head>
<body>
"""
if requestGood == False:
print "<h1>Problem communicating with the server</h1>"
print "<p>" + results + "</p>"
elif (len(results["results"]["bindings"]) == 0):
print "<p>No results found.</p>"
else:
for result in results["results"]["bindings"]:
print "<p>" + result["actorName"]["value"] + "</p>"
print "</body></html>"
main()
|
A linha sys.path.append foi necessária quando executei o script em um serviço de hosting para informar ao interpretador de Python do host onde instalei as bibliotecas SPARQLWrapper e JSON que fazem parte da distribuição Python padrão.
Após importar as bibliotecas necessárias e armazenar os valores de nomes de diretores passados do formulário HTML nas variáveis
dir1name e dir2name , o script configura a consulta SPARQL e envia a mesma ao terminal
SPARQL. Esse terminal é identificado por uma URL passada como um argumento quando o objeto SPARQLWrapper é criado armazenado no objeto sparql do script.
A consulta armazenada na variável queryString é semelhante àquela vista anteriormente que procurava atores que haviam aparecido em filmes de ambos os Coppolas, exceto pelas cadeias
DIR1-NAME e DIR2-NAME que são substituídas pelos valores dir1name e dir2name após a variável queryString ser criada.
Após configurar a cadeia de procura e identificar o formato no qual deseja os dados retornados como JSON, um bloco try/except envia a consulta ao servidor e configura uma variável requestGood para indicar se o pedido foi bem-sucedido. Após gerar a saída do cabeçalho de uma página HTML, o script gera uma dessas três saídas:
- Uma mensagem de erro simples se o pedido não tiver sido bem-sucedido.
- Uma mensagem "Nenhum resultado localizado" se uma consulta sem erros não tiver localizado nenhum resultado.
- O nome de cada ator como um único parágrafo HTML.
O script foi concluído emitindo a saída dos elementos body e html da página HTML.
Aplicativo Dois: Discos, seus Artistas e Datas de Lançamento
Suas qualificações em HTML e CSS podem ajudá-lo a construir um aplicativo com aparência mais elegante do que meu demo commonActors. Para criar um aplicativo que não apenas tem uma melhor aparência, mas também faz mais, observe que a instrução SELECT na consulta SPARQL acima somente solicita uma informação para cada padrão correspondido: o nome do ator. Consultas SPARQL típicas, como consultas SQL típicas, solicitam mais do que isso e, à medida que o programa gravado na linguagem de seu host (em meu exemplo acima, Python) passa pelos resultados de consulta recuperados, pode fazer todo o tipo de coisa interessante com as informações recuperadas.
As reais possibilidades, no entanto, estão na opção mais ampla de dados disponíveis.
Indo além de linkedmdb.org, é possível localizar outros terminais SPARQL públicos que fornecem acesso a uma gama mais ampla de dados.
Uma das maiores e mais populares coletas de dados SPARQL é DBpedia, um esforço comunitário para extrair dados estruturados de "Caixas de Informações" da Wikipedia (as informações de campos nas caixas cinzas do lado direito de muitas páginas da Wikipedia) e armazenar os mesmos onde podem ser recuperados com consultas SPARQL.
Ao ouvir música, frequentemente fico imaginando quando um disco específico foi lançado, portanto, gravei o aplicativo simpleAlbumQuery para facilitar essa consulta.
(Na verdade, ao escrever o primeiro rascunho deste artigo, eu estava ouvindo uma seleção de músicas de Duke Ellington e, enquanto ouvia a versão de Diana Krall de
"I'm Just a Lucky So and So", consultei-a em http://www.snee.com/sparqlforms/simpleAlbumQuery.html, onde tenho uma cópia do aplicativo armazenada.
Experimente!) No arquivo zip que acompanha este artigo, juntamente com o arquivo
commonActors.html, o arquivo commonActors.cgi e a folha de estilo
simple.css que eles usam, encontrará um arquivo de página da Web simpleAlbumQuery.html e o script CGI em Python simpleAlbumQuery.cgi. (Consulte Download.)
Para o aplicativo simpleAlbumQuery, a Figura 2 mostra o formulário HTML que possui dois campos para passar os parâmetros
artist e album para o script CGI em Python.
(Visualize uma versão maior.)
Figura 2. Formulário de Entrada para o Aplicativo SimpleAlbumQuery
Esse formulário inclui algumas consultas sugeridas como introdução para o usuário. Além de preencher os valores sugeridos no formulário, o usuário pode clicar em um dos links experimente . Por exemplo, clicar no segundo link experimente ativa a URL http://www.snee.com/sparqlforms/simpleAlbumQuery.cgi?artist=&album=Fillmore, que tem o mesmo efeito que inserir nada no primeiro campo do formulário, Fillmore no segundo e, então, clicar no botão de procura : chama o script simpleAlbumQuery.cgi, passando uma cadeia vazia como o valor do artista e Fillmore como o disco um.
A Figura 3 mostra as três primeiras entradas resultantes da consulta de amostra
Fillmore . Juntamente com um pouco de CSS para ter uma melhor aparência, inclui as imagens das capas dos discos e o link dos nomes dos discos para as páginas da Wikipedia para esses discos.
(Rolar para baixo nos resultados retornados revelará dois discos de
Miles Davis em Fillmore em 1970. Se for o mesmo show que o listado no letreiro para Neil Young and Crazy Horse na terceira linha da Figura 3, então, é um bom exemplo de descoberta ao acaso de Dados Vinculados
—e deve ter sido um ótimo show.)
Figura 3. Primeiras Três Entradas Retornadas pela Consulta para o Artista = "" e Disco = "Fillmore"
Além de um pouco de manipulação de cadeia de caracteres para formatar algum texto retornado, verá que simpleAlbumQuery.cgi possui somente duas diferenças significativas de commonActors.cgi:
- A consulta é enviada a um destino diferente, de forma que uma URL diferente seja passada ao método de criação
SPARQLWrapper : http://dbpedia.org/sparql, a URL do terminal SPARQL para DBpedia.
- A variável
queryString armazena uma consulta diferente que solicita informações diferentes e, para customizar a consulta para o usuário do aplicativo simpleAlbumQuery, valores diferentes são passados a ela a partir do formulário HTML.
Dê uma olhada mais de perto na consulta na Lista 6. (Enquanto DBpedia possui seu próprio formulário SNORQL para inserir consultas diretamente em http://dbpedia.org/snorql/, essa consulta não funcionará conforme mostrado, pois possui as cadeias de caracteres marcadoras ARTIST-STRING e ALBUM-TITLE-STRING que, como com DIR1-NAME e DIR2-NAME no aplicativo commonActors, serão substituídas antes de a consulta ser enviada ao servidor do terminal SPARQL.)
Lista 6. Consulta SPARQL para o Aplicativo albumQuery
PREFIX dbpedia2: <http://dbpedia.org/property/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?artistName ?album
?wpURL ?releaseDate ?coverURL
WHERE {
?s dbpedia2:artist ?artist;
dbpedia2:name ?album;
foaf:page ?wpURL;
dbpedia2:released ?releaseDate;
dbpedia2:cover ?coverURL.
?artist rdfs:label ?artistName.
FILTER (regex(?artistName, "ARTIST-STRING")).
FILTER (regex(?album, "ALBUM-TITLE-STRING")).
FILTER (lang(?artistName) = "en").
}
LIMIT 30
|
Cada entrada da DBpedia que corresponde a páginas da Wikipedia tem um identificador URI com diversas informações associadas a cada uma delas.
Isso inclui entradas para discos, de forma que a consulta solicite o identificador do artista de um disco, o nome do disco e a URL da Wikipedia para construir os links da
Figura 3, a data de lançamento e a URL da capa para exibir a imagem na saída.
Quando tiver o identificador do artista, você irá querer mostrar aos usuários o nome legível por seres humanos em vez de o identificador URI, de forma que a consulta solicita
rdfs:label que acompanha o identificador do artista.
Como a consulta especifica os discos desejados? Usando a palavra-chave FILTER de SPARQL para indicar que você deseja somente um nome de artista e nome de disco que corresponda aos padrões indicados.
Como com o aplicativo commonActors, essa consulta possui cadeias de caracteres simuladas que são substituídas pelo script CGI antes de o script ser enviado ao terminal SPARQL.
Como a DBpedia pode armazenar diversos nomes para um artista, dependendo de como as pessoas fazem referência ao artista em diferentes idiomas, uma terceira instrução FILTER mostra que você deseja somente a versão em inglês do nome do artista.
Para ser educado com o servidor da DBpedia, essa consulta também inclui uma instrução LIMIT 30 para evitar que recupere muitos dados. Por exemplo, se um usuário do aplicativo simpleAlbumQuery inserir a letra "a" como o título de um disco e deixar o campo do artista em branco, a consulta solicita da DBpedia todos os discos com a letra "a" no título de qualquer artista no banco de dados e isso é pedir um pouco de mais.
À medida que verifica as outras partes de simpleAlbumQuery.cgi e simpleAlbumQuery.html, fora da consulta SPARQL, descobrirá que o código de cada um tem um paralelo com algum código correspondente dos arquivos commonActors.
Seu Próprio Aplicativo
Ao localizar um terminal SPARQL com dados que são úteis para você ou para seus usuários, é possível criar seu próprio formulário HTML e um script CGI com base na estrutura dos dois aplicativos incluídos neste artigo e, então, construir um aplicativo que usa esses dados.
Toda vez que uma Caixa de Informações da Wikipedia é vista, é divertido se lembrar que é possível criar um aplicativo como commonActors ou simpleAlbumQuery para usar esses dados. E apesar de a
lista de terminais SPARQL do W3C
crescente incluir muitos outros bancos de dados de informações relacionadas a música, você encontrará muitos outros também, principalmente nos campos de literatura, biologia e indústria farmacêutica. Para ir ainda além, nada impede que um único aplicativo recupere dados de diversos terminais e construa algo novo a partir da coleta, criando aplicativos ainda mais complexos e interessantes. O único limite é sua imaginação.
Download | Descrição | Nome | Tamanho | Método de download |
|---|
| Sample Python, HTML, and CSS for this article | WPQueryFormApps.zip | 5KB | HTTP |
|---|
Recursos Aprender
Obter produtos e tecnologias
Discutir
Sobre o autor  | 
|  | Bob DuCharme, um arquiteto de soluções da Innodata Isogen, era um especialista em XML quando XML não era muito utilizado. Escreveu quatro livros e praticamente cem artigos on-line e impressos sobre tecnologia da informação usando a palavra "funcionalidade" em todos eles. Consulte http://www.snee.com/bob para obter informações adicionais e www.snee.com/bobdc.blog para seu weblog. |
Avalie esta página
|  |