2017-02-23 3 views
0

Ich möchte JSON-Daten von UN COMTRADE importieren. Also schrieb ich eine Liste der gültigen Länder und Jahre und dann lief ich eine Schleife, die OK funktioniert, außer wenn ein bestimmtes Jahr keine Daten für ein Land enthält.Wie überprüfe ich einen gültigen API-Aufruf in R? RCurl und httr helfen im Moment nicht

Da ich testen wollen, ob mein API-Aufruf gültig ist, so dass ich dies schreibe:

library(RCurl) 

# this is an actual valid API call  
string = "http://comtrade.un.org/api/get?max=50000&type=C&freq=A&px=S2&ps=2010&r=4&p=all&rg=2&cc=AG4&fmt=json" 

url.exists(string, useragent="curl/7.47.0 RCurl/1.95-4.8") 

Aber auch für gültigen Ländercodes und Jahre, die auf dem Internet-Browser als JSON Text angezeigt werden können die R-Ausgang, sagt

url.exists(string, useragent="curl/7.47.0 RCurl/1.95-4.8") 
[1] FALSE 

Mit httr I

library(httr) 
!http_error(string) 

tun ein d Ich erhalte [1] FALSE

Wie kann ich dieses falsch negative Ergebnis beheben?

+0

Können Sie den Inhalt von 'httr :: GET (string)' überprüfen, zum Beispiel, schauen Sie sich den Statuscode der Abfrage an: 'httr :: GET (string) [['status_code']]' '. – SymbolixAU

Antwort

1

nahm ich einen Peak bei url.exists(), und dann schrieb diese einfachere Version

> g = basicTextGatherer() 
> x = curlPerform(url=string, headerfunction=g$update, nobody=TRUE) 
> g$value() 
[1] "HTTP/1.1 302 Moved Temporarily\r\nLocation: https://comtrade.un.org/api/get?max=50000&type=C&freq=A&px=S2&ps=2010&r=4&p=all&rg=2&cc=AG4&fmt=json\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nDate: Thu, 23 Feb 2017 23:09:13 GMT\r\nAge: 0\r\nConnection: close\r\nVia: 1.1 localhost.localdomain\r\n\r\n" 

Die http: url :, auf https umgeleitet wird, so habe ich versucht,

> string = sub("http", "https", string) 
> g = basicTextGatherer() 
> x = curlPerform(url=string, headerfunction=g$update, nobody=TRUE) 
> g$value() 
[1] "HTTP/1.1 405 Method Not Allowed\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nAllow: GET\r\nContent-Length: 73\r\nContent-Type: application/json; charset=utf-8\r\nExpires: -1\r\nServer: Microsoft-IIS/7.5\r\nX-AspNet-Version: 4.0.30319\r\nX-Powered-By: ASP.NET\r\nDate: Thu, 23 Feb 2017 23:11:02 GMT\r\n\r\n" 

Die Methode 'HEAD' , impliziert durch die Curl-Option nobody, wird nicht unterstützt. Dies ist auch der Grund, warum httr::http_error() fehlschlägt - weil es eine HEAD-Anfrage ausführt. Es ist eine Entscheidung auf der Serverseite, HEAD-Anfragen nicht zu unterstützen, also nichts, was auf der Benutzerseite getan werden kann.

Sie könnten auch versuchen, nur ein einzelnes Byte zu erhalten (z. B. RCurl::getURL(string, followlocation=TRUE, range="0-1")), aber das wird möglicherweise auch nicht unterstützt (und nicht für diese Abfrage - die gesamte Abfrageantwort wird zurückgegeben).

Der einzige Weg, den ich testen kann, ob die Datei tatsächlich existiert, besteht darin, sie abzurufen. Ich würde verwenden httr::GET(), vielleicht wie

tryCatch({ 
    response <- httr::GET(string) 
    stop_for_status(response) 
    ## ... 
}, http_error=function(e) { 
    ## log error or otherwise recover 
}) 

Dies ist wahrscheinlich eine effizientere Lösung sowieso. Wenn die Abfrage erfolgreich ist, erfordert die erste Überprüfung und dann die Durchführung der Abfrage zwei Netzwerkaufrufe, während die Durchführung der Abfrage ohne Prüfung nur ein Netzwerkaufruf ist. Wenn die Abfrage fehlschlägt, ist bei beiden Ansätzen nur ein einziger Netzwerkaufruf erforderlich, und der Rückgabewert ist ähnlich kompakt. Daher speichern wir die Latenz, die durch einen Netzwerkanruf im häufigsten Szenario verursacht wird.

Verwandte Themen