我将遵循these instructions提交sparql查询,因为查询可能很长,所以更喜欢post方法。但是,即使get起作用,它似乎也会失败——有什么方法可以让post查询起作用吗?
sparql = <<END
SELECT ?item ?itemLabel
WHERE
{
?item wdt:P31 wd:Q146.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
END
# Fails with 405 Not writable
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}")
puts resp.status, resp.body
# Works with 200
resp = Excon.get("https://query.wikidata.org/sparql?query=#{URI::encode(sparql)}")
puts resp.status, resp.body
我也试过发送
"Content-Type" => "application/x-www-form-urlencoded"
,但运气不好。 最佳答案
感谢上面的评论者展示了有效的例子。我根据所有明显的组合做了进一步的检查,如下所示。
综上所述:
如果get很短并且可能被重用,请使用get(因为get查询是缓存的)
确保发送user-agent
头,并注意某些库在默认情况下不包含头(否则将返回一个无法解释的403)
对于post,最好也是最简单的方法(在我看来)是将sparql查询作为整个主体发送,将“content type”作为“application/sparql查询”,这里不需要对查询进行编码。您也可以使用“content type”为“application/x-www-form-urlencoded”的表单语法,并确保对查询进行了编码。
require 'excon'
# any arbitrary query
sparql = 'SELECT ?item ?itemLabel WHERE { ?item wdt:P31 wd:Q146. SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } }'
# SUCCESS!
resp = Excon.get("https://query.wikidata.org/sparql?query=#{URI::encode(sparql)}")
puts "GET", resp.status, resp.body[0,100], "\n"
# FAIL! 403 (need user agent)
headers = { "Content-Type" => "application/sparql-query" }
resp= Excon.post('https://query.wikidata.org/sparql', body: sparql, headers: headers)
puts "POST sparql-query", resp.status, resp.body[0,100], "\n"
# SUCCESS!
headers = { "Content-Type" => "application/sparql-query", "User-Agent" => "Ruby 2.6.4" }
resp= Excon.post('https://query.wikidata.org/sparql', body: sparql, headers: headers)
puts "POST sparql-query with user-agent", resp.status, resp.body[0,100], "\n"
# FAIL! 403 (need user agent)
headers = { "Content-Type" => "application/x-www-form-urlencoded" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST form", resp.status, resp.body[0,100], "\n"
# SUCCESS!
headers = { "Content-Type" => "application/x-www-form-urlencoded", "User-Agent" => "Ruby 2.6.4" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST form with user-agent", resp.status, resp.body[0,100], "\n"
# FAIL! 405 (need encoding)
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}")
puts "POST plain", resp.status, resp.body[0,100], "\n"
# FAIL! 405 (need encoding)
headers = { "User-Agent" => "Ruby 2.6.4" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST plain with user-agent", resp.status, resp.body[0,100], "\n"
更多信息
SPARQL 1.1 Protocol
Phabricator issue
Wikimedia User-Agent policy