【问题标题】:How to access the Wikidata SPARQL interface from Java?如何从 Java 访问 Wikidata SPARQL 接口?
【发布时间】:2016-09-20 18:55:17
【问题描述】:

我正在尝试从 Wikidata 查询实体的所有实例。我发现目前唯一的方法是使用 SPARQL 端点。

我找到了一个示例查询,它与我想做的事情有关,并从 Web 界面成功执行了它。不幸的是,我似乎无法从我的 Java 代码中执行它。我正在使用 openRDF SPARQL 库。这是我的相关代码:

SPARQLRepository sparqlRepository = new SPARQLRepository(
        "https://query.wikidata.org/");
SPARQLConnection sparqlConnection = new SPARQLConnection(
        sparqlRepository);

String query = "SELECT ?s ?desc ?authorlabel (COUNT(DISTINCT ?sitelink) as ?linkcount) WHERE {"
        + "?s wdt:P31 wd:Q571 ."
        + "?sitelink schema:about ?s ."
        + "?s wdt:P50 ?author"
        + "OPTIONAL { ?s rdfs:label ?desc filter (lang(?desc) = \"en\"). }"
        + "OPTIONAL {"
        + "?author rdfs:label ?authorlabel filter (lang(?authorlabel) = \"en\")."
        + "}"
        + "} GROUP BY ?s ?desc ?authorlabel ORDER BY DESC(?linkcount)";

TupleQuery tupleQuery = sparqlConnection.prepareTupleQuery(
        QueryLanguage.SPARQL, query);
System.out.println("Result for tupleQuery" + tupleQuery.evaluate());

这是我收到的回复:

Exception in thread "main" org.openrdf.query.QueryEvaluationException: <html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.9.4</center>
</body>
</html>
    at org.openrdf.repository.sparql.query.SPARQLTupleQuery.evaluate(SPARQLTupleQuery.java:59)
    at main.Test.main(Test.java:72)
Caused by: org.openrdf.repository.RepositoryException: <html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.9.4</center>
</body>
</html>
    at org.openrdf.http.client.HTTPClient.handleHTTPError(HTTPClient.java:953)
    at org.openrdf.http.client.HTTPClient.sendTupleQueryViaHttp(HTTPClient.java:718)
    at org.openrdf.http.client.HTTPClient.getBackgroundTupleQueryResult(HTTPClient.java:602)
    at org.openrdf.http.client.HTTPClient.sendTupleQuery(HTTPClient.java:367)
    at org.openrdf.repository.sparql.query.SPARQLTupleQuery.evaluate(SPARQLTupleQuery.java:52)
    ... 1 more

通常我会假设这意味着我需要某种 API 密钥,但 Wikidata API 似乎是完全开放的。我是不是在设置连接时出错了?

【问题讨论】:

标签: java sparql wikidata sesame


【解决方案1】:

正确的 Wikidata 端点 URL 是 https://query.wikidata.org/sparql - 你错过了最后一点。

此外,我注意到您的代码中存在一些小故障。首先,您正在这样做:

SPARQLConnection sparqlConnection = new SPARQLConnection(sparqlRepository);

应该是这样的:

RepositoryConnection sparqlConnection = sparqlRepository.getConnection();

始终使用 getConnection()Repository 对象中检索您的连接对象 - 这意味着资源是共享的,Repository 可以在必要时关闭“悬空”连接。

其次:你不能打印出这样的查询结果:

System.out.println("Result for tupleQuery" + tupleQuery.evaluate());

如果您希望将结果打印到System.out,您应该这样做:

tupleQuery.evaluate(new SPARQLResultsTSVWriter(System.out));

或者(如果您希望更多地自定义结果):

for (BindingSet bs : QueryResults.asList(tupleQuery.evaluate())) {
    System.out.println(bs);
}

对于它的价值 - 通过上述更改,查询请求运行,但看起来您的查询对于 Wikidata 来说太“重” - 至少我从服务器收到超时错误。不过尝试一个更简单的查询,您会看到代码有效。

【讨论】:

  • 感谢您提供这些有用的提示。我使用 Sysout 作为测试,它应该调用 tupleQuery.evaluate() 的 toString() 方法,这足以看看它是否有效。
【解决方案2】:

当我转到 https://query.wikidata.org/ 并查看工具 > SPARQL REST 端点时,我看到了(添加了重点):

SPARQL 端点

SPARQL 查询可以通过向 https://query.wikidata.org/sparql?query={SPARQL} 的 GET 请求直接提交到 SPARQL 端点(POST 和其他方法请求将被“403 Forbidden”拒绝)。*结果默认以 XML 形式返回,如果提供了查询参数 format=json 或标头 Accept: application/sparql-results+json,则以 JSON 形式返回。

看起来您使用的是不同的 URL(看起来您没有最终的 sparql),所以您实际上可能没有到达那个端点。

也就是说,由于您可以访问 使用的 URL(可能使用 GET),听起来您的 API 调用可能正在执行 POST,因此您可能需要检查查询的方式也在通过网络。

Use Jena to query wikidata 中有一个使用 Jena 端点的示例。该问题的 OP 实际上与您遇到的问题相同(错误的查询 URL)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 2022-01-14
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多