2016-08-05 152 views
1

我需要检索已执行的VirusTotal扫描的结果,提供文件的哈希值,而不再次发送文件。 您可以找到API here的文档。python中的json VirusTotal API调用错误

我基本上需要发送这种格式的json:{"resource": "hash", "apikey": api}。 我使用请求,它是非常有用的,它应该处理json,即使不使用jsonsimplejson模块。

如果我发送一个请求,这样它的工作原理:

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

,但我有很多的哈希值,所以我需要生成JSON编程,而不是在程序中硬编码的。

首先我尝试使用字典: 的API键不会改变,所以我把分配圈外的,而不是为哈希我遍历散列的列表称为MD5

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

我得到一本字典为每一个循环,我传递给请求 API调用。 代表JSON的字典是这样的格式:

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

文档显示resource作为JSON的第一要素,相反在我的生成字典,我得到了apikey第一,无论如何,如果他们实施正确JSON标准,为了应该没关系。无论如何,这不是一个有效的JSON格式,因为它包含单引号,它应该包含双引号。我想避免使用另一个模块,但我尝试使用jsonsimplejson模块将字典转换为有效的json(使用双引号),并且它显然工作正常。我知道请求也有一个json =参数,你可以传递一个字典,它应该把它编码为json给你,但我不确定它是否工作。否则,您只需使用data =参数并在发出请求时将json分配给它。

如果我提出这样的要求:

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()) 

我得到这个错误:

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) 

线15在我的代码是由print(r.json())

表示,如果我print(r.text())而是说TypeError: 'str' object is not callable


然后我试图仍然使用json模块稍微不同的方法而不经过一个预先定义的词典:

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

其中hashapi是2个字符串。

我仍然得到了同样的错误:

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) 

从错误似乎问题出在获取或解码JSON响应,但我不知道,如果问题是该请求未正确发送第一个地方。 如果不是打印json响应我做print(r.status_code())我得到一个状态。

这是一个典型的HTTP状态,意思是“Forbidden”,并且病毒总API文档还说:If you try to perform calls to functions for which you do not have the required privileges an HTTP Error 403 Forbidden is raised

回答

1

我注意到我使用了一个名为hash的变量,它可能会导致一个问题,因为它可能会被Python解释器误认为一个方法,所以我将它重命名为file_hash。然后,而不是使用r.json我用r.text用于获取响应作为文本,然后我通过它作为一个参数传递给功能json.loads,我存储在名为response变量的值。 response是一个字典,它包含键和单引号,而不是双引号就像在一个有效的JSON包裹值,所以只好当我想从响应提取值来考虑到这一点。代码运行后,我现在没有收到任何错误。唯一的问题是,在几个检索到的jsons(正好是4)后,我得到了和以前一样的错误:simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 这可能是因为我没有得到json响应。如果你问为什么,这是因为公共API只支持4个请求/分钟,所以我必须实现一个休眠功能,以便每4个请求暂停1分钟的报告检索。 (我从一开始就知道这一点)。我实现了其他几项检查,并在功能我的代码,反正我告诉你,工作的基本代码:

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