Инструмент командной строки для запроса Викиданных (или другой конечной точки SPARQL)

В терминале Linux я хочу запустить запрос SPARQL и получить результат в виде CSV:

$ query --service https://query.wikidata.org/sparql?query=SPARQL --sparql "SELECT ?i ?c WHERE { ?i wdt:P31 wd:Q3917681. ?i wdt:P137 ?c.}"
wd:Q4374016,wd:Q819
wd:Q4374028,wd:Q711
wd:Q4374063,wd:Q874
wd:Q4374039,wd:Q159

... или что-то подобное.

Требования:

  • Бесплатный, с открытым исходным кодом
  • Работает с Викиданными
  • Работает в Linux
  • Бонус, если он может обрабатывать обычные префиксы пространства имен без необходимости указывать их в командной строке.
  • Необходимость писать запрос в текстовом файле также приемлема.

Ответы (4)

Для большинства приложений достаточно базового подхода командной строки. Учитывая запрос в файле query.sparql, получите CSV с помощью curl:

curl -X POST https://query.wikidata.org/sparql -H "Accept: text/csv" --data-urlencode query@query.sparql

Вот еще один скрипт bash , который также поддерживает вывод JSON, например, для обработки с помощью jq:

#!/bin/bash
#
# Run a Wikidata query from command line
# 
# Usage examples:
#
#   wdquery "DESCRIBE wd:Q42"
#   wdquery - xml < query.sparql
#   wdquery query.sparql json
#

QUERY=${1--}        # SPARQL query or file
FORMAT=${2-json}    # output format

ENDPOINT=https://query.wikidata.org/sparql

# make sure query is written to a file
if ! [ -f "$QUERY" ]
then
    TMPFILE="$(mktemp)"
    if [ "$QUERY" == "-" ]
    then
        # read query from STDIN
        cat > "$TMPFILE"
    else
        # write query to file
        echo "$QUERY" > "$TMPFILE"
    fi
    QUERY="$TMPFILE"
fi

curl -s -X GET -F "query=@$QUERY" "$ENDPOINT?format=$FORMAT"

[ -z "$TMPFILE" ] || rm "$TMPFILE"

Я написал этот bash-скрипт , чтобы разрешить простые запросы к Викиданным из командной строки.

Применение:

./query-wikidata.sh "SELECT DISTINCT ?item WHERE {?item wdt:P31 wd:Q3917681. ?item wdt:P137 wd:Q16. ?item wdt:P131*/wdt:P17 wd:Q142.}"

ИЛИ этот более читаемый синтаксис:

echo "
 SELECT DISTINCT
   ?item
 WHERE {
   ?item wdt:P31 wd:Q3917681.
   ?item wdt:P137 wd:Q16.
   ?item wdt:P131*/wdt:P17 wd:Q142.
 }
 " |./query-wikidata.sh

Выход:

<?xml version='1.0' encoding='UTF-8'?>
<sparql xmlns='http://www.w3.org/2005/sparql-results#'>
        <head>
                <variable name='item'/>
        </head>
        <results>
                <result>
                        <binding name='item'>
                                <uri>http://www.wikidata.org/entity/Q137798</uri>
                        </binding>
                </result>
        </results>
</sparql>

Плюс некоторая сетевая информация по выводу ошибок.

Он знает стандартные префиксы Викиданных.
Лицензия: GNU-GPLv3

ссылка на скрипт не работает по состоянию на 12 февраля 2022 г.
@wolfgang fahl: исправлено, спасибо, что сообщили мне!

Он не распознает префиксы Викиданных по умолчанию и не может выводить CSV на данный момент, но консоль RDF4J — полезное универсальное приложение командной строки, не только для связи с Викиданными, но и с любой общедоступной конечной точкой SPARQL, вашим собственным сервером RDF4J, или даже собственный простой встроенный тройной магазин.

Для установки вам потребуется среда выполнения Java (8). Затем просто загрузите RDF4J SDK . Скрипт console.shможно найти в bin/каталоге.

Чтобы запросить Викиданные, запустите консоль и добавьте новое определение конечной точки SPARQL:

./console.sh 
Connected to default data directory
RDF4J Console 2.0.1
Type 'help' for help.
> create sparql
Please specify values for the following variables:
SPARQL query endpoint: https://query.wikidata.org/sparql
SPARQL update endpoint: 
Local repository ID [endpoint@localhost]: wikidata
Repository title [SPARQL endpoint repository @localhost]: wikidata sparql endpoint
Repository created

После настройки вы можете открыть созданный репозиторий (который является просто прокси для общедоступной конечной точки SPARQL):

> open wikidata
Opened repository 'wikidata'

Затем просто запросите (стараясь не перегружать конечную точку — используйте limitпредложения, если вы экспериментируете):

wikidata> select * where {?x rdf:type ?o } limit 10
Evaluating SPARQL query...
+-------------------------------------+-------------------------------------+
| x                                   | o                                   |
+-------------------------------------+-------------------------------------+
| <http://wikiba.se/ontology#Dump>    | <http://schema.org/Dataset>         |
| <http://www.wikidata.org/value/8000b1b66dfb1c74420cf59f0388d425>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/8000d3ac475ff41c5e2e38ffda574d1c>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/8000f71177f50273969eca2096803e29>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/80018edb4bf3ecf344a2d4343d76235c>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/800269618da5a8571140652500ade834>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/8003743c7dbef48511f9df4e629fd462>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/8003a8ceaf4f75884d2b9ff99e3c959c>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/80062f03a3a91733e0eb81f50ca56208>| <http://wikiba.se/ontology#GeoAutoPrecision>|
| <http://www.wikidata.org/value/800682cb1e9157517ed01b1a4b1760bc>| <http://wikiba.se/ontology#GeoAutoPrecision>|
+-------------------------------------+-------------------------------------+
10 result(s) (1231 ms)

Вышеупомянутое все делается в интерактивном режиме, но, конечно, вы можете написать эти команды, а затем просто передать их в console.shсценарий оболочки.

FWIW, спецификация формата вывода находится в списке ToDO , как и пользовательское определение пространств имен .

Что касается ваших требований, по пунктам:

  • RDF4J с открытым исходным кодом ( лицензия EDL )
  • Он работает с Викиданными или любой другой конечной точкой SPARQL.
  • Работает на Linux или любой другой ОС (Java)
  • Не поддерживает (пока) обработку префиксов пространств имен без их указания (по крайней мере, не для конечных точек SPARQL).
  • Вам не обязательно писать запрос в текстовом файле, но вы можете, если хотите

Существует инструмент командной строки на основе Perl wdqс 2016 года, на Github и на CPAN .

С запросом

wdq -tplanet '?planet wdt:P31 wd:Q44559; wdt:P397 ?sun' > stars-and-exoplanets.json

вы получите набор результатов JSON.

Вам не нужно указывать префиксы пространства имен, а wdqтакже внедрять службу меток в запрос SPARQL. Прочтите сообщение об OpenData.SE пользователя Jakob .

Вы можете преобразовать JSON в CSV с помощью jq.

< stars-and-exoplanets.json jq -r    \
'. | map({"p":.planet, "pl":.planetLabel,  "pd":.planetDescription, "sun":.sun})'  \
 | jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' \
> stars-and-exoplanets.csv

JSON:

# < stars-and-exoplanets.json jq  '.[0]'
# first record of ~3000
{
  "planet": "http://www.wikidata.org/entity/Q1198042",
  "planetDescription": "extrasolar planet",
  "planetLabel": "HD 37124 d",
  "sun": "http://www.wikidata.org/entity/Q139390"
}

CSV (первые 2 строки):

# < sun-and-stars-and-exoplanets.csv head -2

"p","pd","pl","sun"
"http://www.wikidata.org/entity/Q1198042","extrasolar planet","HD 37124 d","http://www.wikidata.org/entity/Q139390"