我正在尝试从Wikidata查询实体的所有实例。我发现目前唯一的方法是使用SPARQL-API。
我找到了一个示例查询,它可以解决我想要做什么并从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似乎是完全开放的。我是否在设置连接时出错?
答案 0 :(得分:4)
维基数据的正确端点网址为https://query.wikidata.org/sparql
- 您错过了最后一位。
另外,我注意到你的代码中有一些小问题。首先,你是这样做的:
SPARQLConnection sparqlConnection = new SPARQLConnection(sparqlRepository);
这应该是这样的:
RepositoryConnection sparqlConnection = sparqlRepository.getConnection();
始终使用Repository
从getConnection()
对象检索您的连接对象 - 这意味着资源是共享的,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);
}
对于它的价值 - 通过上述更改,查询请求会运行,但看起来您的查询对于维基数据来说太“重” - 至少我从服务器收到了超时错误。尝试一个更简单的查询,你会看到代码工作。
答案 1 :(得分:2)
当我转到https://query.wikidata.org/并查看工具&gt; 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。
看起来你正在使用不同的网址(看起来你看起来没有最终sparql
),所以你可能实际上没有点击那个端点。
也就是说,既然您可以访问 使用的网址(可能是使用GET),听起来您的API调用可能正在进行POST,因此您可能需要检查查询的方式正在通过网络。
在Use Jena to query wikidata中有一个使用Jena的此端点的示例。该问题的OP实际上遇到了您遇到的相同问题(错误的查询URL)。