在python

时间:2016-08-05 10:31:09

标签: python json python-requests

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

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

如果我发送这样的请求,那就有效:

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())获得 403 状态。

这是典型的HTTP状态,表示“Forbidden”,而且Virus Total 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 个答案:

答案 0 :(得分:1)

我注意到我使用了一个名为hash的变量,它可能会导致一个问题,因为它可能会被Python解释器的方法弄错,所以我将其重命名为file_hash。然后我使用r.json而不是r.text来获取作为文本的响应,然后我将它作为参数传递给函数json.loads,我将值存储在一个名为{{1的变量中}}。 response是一个字典,它包含由单引号包装的键和值,而不是像有效json中的双引号,所以当我想提取值时,我必须考虑到这一点从回应。我现在没有收到任何错误,代码运行。唯一的问题是,在一些检索到的jsons(正好是4个)之后,我得到了与以前相同的错误:response 这可能是因为我不再获得json响应。如果你问为什么,那是因为公共API最多只支持 4个请求/分钟,所以我必须实现一个休眠功能,以暂停每1分钟的报告检索4个要求。 (从一开始我就知道这一点)。我在我的代码中实现了其他几个检查和功能,无论如何,我向您展示了有效的基本代码:

simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)