2016-08-05 48 views
1

Ich muss das Ergebnis der VirusTotal-Scans bereits durchgeführt, die den Hash der Dateien, ohne die Datei erneut zu senden. Sie finden die Dokumentation der API here.Fehler mit Json VirusTotal API Aufruf in Python

Ich muss im Grunde ein JSON dieses Formats senden: {"resource": "hash", "apikey": api}. Ich benutze Anfragen, es ist sehr nützlich und es sollte Json auch ohne die Verwendung der JSON oder simplejson Modul.

, wenn ich eine Anfrage wie folgt senden es funktioniert:

r = requests.post(url, data = {"resource": "dbbe9c39df7c355f970e3a9636fbac04" , "apikey": "myapikey"} 
print(r.json()) 

aber ich habe viele Hashes, damit ich die json programmatisch statt hartzucodieren es in dem Programm generieren müssen.

Zuerst habe ich versucht, ein Wörterbuch mit: die api Taste ändert sich nicht so habe ich den Auftrag aus der Schleife, anstatt für die Hash I Schleife durch eine Liste von Hashes genannt md5 .

params = {} 
params["apikey"] = api 
for hash in md5: 
    params["resource"] = hash 

ich ein Wörterbuch für jede Schleife, die ich Anfragen übergeben für den API-Aufruf. Das Wörterbuch die json repräsentiert ist dieses Format:

{'apikey': myapikey', 'resource': 'hash'} 

Die Dokumentation zeigt resource als erstes Element des json, statt in meinem erzeugt Wörterbuch bekomme ich die apikey ersten, trotzdem, wenn sie richtig den json Standard implementieren, um sollte nicht wichtig sein. Wie auch immer, das ist kein gültiges JSON-Format, da es einfache Anführungszeichen enthält. Es sollte doppelte Anführungszeichen enthalten. Ich wollte vermeiden, ein anderes Modul zu verwenden, aber ich versuchte mit json oder simplejson Modul für die Konvertierung des Wörterbuchs in einem gültigen JSON (mit doppelten Anführungszeichen) und es funktioniert anscheinend. Ich weiß, dass Anfragen auch einen json = Parameter haben, wo Sie ein Wörterbuch weitergeben können und es sollte es als JSON für Sie verschlüsseln, aber ich bin mir nicht sicher, es hat funktioniert. Andernfalls können Sie einfach den Parameter data = verwenden und ihm den json zuweisen, wenn Sie die Anfrage stellen.

Wenn ich eine Anfrage wie folgt machen:

params = {} 
params["apikey"] = api 
for hash in md5: 
    params["resource"] = hash 
    json_params = json.dumps(params) 
    r = requests.post(url, data = json_params) 
    print(r.json()) 

ich diesen Fehler:

Traceback (most recent call last): 
    File "C:/Users/Fabio/PycharmProjects/dfir/requests-try-prova.py", line 15, in <module> 
    print(r.json()) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\models.py", line 812, in json 
    return complexjson.loads(self.text, **kwargs) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\__init__.py", line 516, in loads 
    return _default_decoder.decode(s) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\decoder.py", line 370, in decode 
    obj, end = self.raw_decode(s) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\decoder.py", line 400, in raw_decode 
    return self.scan_once(s, idx=_w(s, idx).end()) 
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 

Linie 15 in meinem Code von print(r.json())

dargestellt wird, wenn ich print(r.text()) statt es sagt TypeError: 'str' object is not callable


Dann habe ich versucht, einen etwas anderen Ansatz nach wie vor das json Modul ohne ein vordefiniertes Wörterbuch vorbei:

for hash in md5: 
    r = requests.post(url, data = json.dumps({"resource": hash, "apikey": api})) 
    print(r.json()) 

wo hash und api 2 Strings sind.

ich immer noch die gleichen Fehler:

Traceback (most recent call last): 
    File "C:/Users/Fabio/PycharmProjects/dfir/requests-try-prova.py", line 15, in <module> 
    print(r.json()) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\models.py", line 812, in json 
    return complexjson.loads(self.text, **kwargs) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\__init__.py", line 516, in loads 
    return _default_decoder.decode(s) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\decoder.py", line 370, in decode 
    obj, end = self.raw_decode(s) 
    File "C:\Users\Fabio\AppData\Local\Programs\Python\Python35\lib\site-packages\simplejson\decoder.py", line 400, in raw_decode 
    return self.scan_once(s, idx=_w(s, idx).end()) 
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 

Von dem Fehler scheint es das Problem bekommen oder Dekodieren die json Antwort ist, aber ich frage mich, ob das Problem ist, dass die Anforderung nicht korrekt gesendet wird, in den ersten Platz. Wenn statt der JSON-Antwort ich print(r.status_code()) drucken, bekomme ich einen Status.

Es ist ein typischer HTTP-Status, der "Forbidden" bedeutet und auch die Virus Total API Dokumentation sagt: If you try to perform calls to functions for which you do not have the required privileges an HTTP Error 403 Forbidden is raised.

Antwort

1

Ich bemerkte, dass ich eine Variable namens hash verwendet, und es könnte ein Problem verursachen, weil es mit einer Methode vom Python-Interpreter verwechselt werden kann, so habe ich es in file_hash umbenannt. Dann anstelle von r.json ich r.text für die Antwort als Text und dann habe ich es als Argument an die Funktion json.loads übergeben, speicherte ich den Wert in einer Variablen namens response. response ist ein Wörterbuch und es enthält Schlüssel und Werte von einfache Anführungszeichen anstelle von Anführungszeichen wie in einem gültigen JSON, also musste ich dies berücksichtigen, wenn ich die Werte aus der Antwort extrahieren wollte. Ich bekomme jetzt keinen Fehler, Code läuft. Das einzige Problem ist, dass nach ein paar abgerufenen jsons (genau 4), ich den gleichen Fehler wie zuvor hatte: simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0) Dies ist wahrscheinlich, weil ich keine JSON Antwort mehr bekam. Wenn Sie fragen, warum, ist es, weil die öffentliche API nur bis zu 4 Anfragen/Minute unterstützt, so musste ich eine Schlaf-Funktion implementieren, um den Bericht Abruf für 1 Minute alle 4 Anfragen zu pausieren. (Ich wusste das von Anfang an). Ich habe mehrere andere Überprüfungen und Funktionen in meinem Code implementiert, trotzdem zeige ich Ihnen den grundlegenden Code, der funktioniert:

for file_hash in md5: 
     params = {"apikey": api, "resource": file_hash} 
     r = requests.post(url, data=params) 
     report = json.loads(r.text) 
     print(report)