Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
VirusTotal API v3 URL扫描:正确获取分析报告的实践指南_创想鸟

VirusTotal API v3 URL扫描:正确获取分析报告的实践指南

VirusTotal API v3 URL扫描:正确获取分析报告的实践指南

针对VirusTotal API v3进行URL扫描时,许多开发者常混淆分析ID与URL资源ID,导致获取报告失败。本文详细阐述了如何正确使用API提交URL进行扫描,并利用返回的分析ID查询详细的扫描报告,避免常见的“Wrong URL id”错误,确保成功集成安全检测功能。

VirusTotal API v3 URL扫描流程概述

virustotal提供了一套强大的api,允许开发者自动化地提交文件、url等进行恶意软件检测,并获取详细的分析报告。对于url扫描,其api v3通常遵循两阶段模式:

提交URL进行分析: 通过特定的API端点提交一个URL,VirusTotal会将其加入扫描队列并开始分析。查询分析结果: 在提交URL后,API会返回一个“分析ID”(analysis_id),开发者可以使用这个ID来查询分析任务的当前状态和最终报告。

理解两种关键的标识符至关重要:

分析ID (Analysis ID): 这是提交URL(或其他实体)进行扫描后,VirusTotal为该次分析任务分配的唯一标识符。它的格式通常是 u-{hash}-{timestamp},例如 u-dbae2d0204aa489e234eb2f903a0127b17c712386428cab12b86c5f68aa75867-1701503514。URL资源ID (URL Resource ID): 这是URL本身的唯一标识符,通常是该URL的Base64编码字符串。这个ID用于查询关于该URL资源本身的信息(例如,它以前的扫描历史或元数据),而不是特定分析任务的报告。

常见错误分析:混淆ID与API端点

许多开发者在初次使用VirusTotal API v3时,会遇到一个常见的错误:在提交URL后获取到 analysis_id,但尝试使用 GET /urls/{id} 端点来查询分析报告。这会导致API返回 Wrong URL id 的错误信息。

让我们来看一个典型的错误代码示例:

import requestsdef scanurl_incorrect(scan_url, api_key):    # 步骤一:提交URL进行分析    submit_url_endpoint = "https://www.virustotal.com/api/v3/urls"    payload = { "url": scan_url }    headers = {        "accept": "application/json",        "x-apikey": api_key,    }    response = requests.post(submit_url_endpoint, data=payload, headers=headers)    response.raise_for_status() # 检查HTTP错误    analysis_id = response.json().get('data', {}).get('id', '')    print(f"分析ID: {analysis_id}")    if not analysis_id:        print("未能获取分析ID。")        return    # 步骤二:尝试使用错误的端点获取报告    # 错误之处:这里应该使用 /analyses/{analysis_id},而不是 /urls/{analysis_id}    get_report_endpoint = "https://www.virustotal.com/api/v3/urls/" + analysis_id     headers = {        "accept": "application/json",        "x-apikey": api_key,    }    response = requests.get(get_report_endpoint, headers=headers)    print(response.text)# 示例调用 (请替换为您的实际API Key)# scanurl_incorrect("https://www.youtube.com/", "YOUR_VIRUSTOTAL_API_KEY")

上述代码中,get_report_endpoint 被错误地构建为 https://www.virustotal.com/api/v3/urls/{analysis_id}。然而,GET /urls/{id} 端点期望的 id 是一个URL资源ID(通常是Base64编码的URL),而不是一个 analysis_id。因此,当传入 analysis_id 时,API会识别出这不是一个有效的URL资源ID,从而返回 BadRequestError 和 Wrong URL id 的错误。

正确实现:提交URL与获取分析报告

要正确地获取URL分析报告,关键在于使用正确的API端点:GET /analyses/{analysis_id}。

步骤一:提交URL进行分析

通过 POST /urls 端点提交URL。成功后,响应会包含一个 data 对象,其中 id 字段就是我们需要的 analysis_id。

import requestsimport jsonimport timedef submit_url_for_analysis(scan_url, api_key):    """    提交URL到VirusTotal进行分析。    返回分析ID (analysis_id)。    """    submit_url_endpoint = "https://www.virustotal.com/api/v3/urls"    payload = { "url": scan_url }    headers = {        "accept": "application/json",        "x-apikey": api_key,    }    try:        response = requests.post(submit_url_endpoint, data=payload, headers=headers)        response.raise_for_status() # 检查HTTP错误        response_data = response.json()        analysis_id = response_data.get('data', {}).get('id', '')        if analysis_id:            print(f"URL '{scan_url}' 已提交,分析ID: {analysis_id}")            return analysis_id        else:            print(f"提交URL失败,未能获取分析ID。响应: {response.text}")            return None    except requests.exceptions.RequestException as e:        print(f"提交URL时发生请求错误: {e}")        return None

步骤二:获取URL分析报告

使用从上一步获取到的 analysis_id,通过 GET /analyses/{analysis_id} 端点查询分析报告。由于分析可能需要时间,通常需要进行轮询,直到报告状态变为“完成”(completed)。

def get_analysis_report(analysis_id, api_key, max_retries=10, delay=10):    """    根据分析ID获取VirusTotal的URL分析报告。    会轮询直到分析完成或达到最大重试次数。    """    if not analysis_id:        print("分析ID为空,无法获取报告。")        return None    report_endpoint_base = "https://www.virustotal.com/api/v3/analyses/"    headers = {        "accept": "application/json",        "x-apikey": api_key,    }    for i in range(max_retries):        try:            response = requests.get(f"{report_endpoint_base}{analysis_id}", headers=headers)            response.raise_for_status()            report_data = response.json()            status = report_data.get('data', {}).get('attributes', {}).get('status')            print(f"尝试 {i+1}/{max_retries} - 分析状态: {status}")            if status == 'completed':                return report_data            elif status == 'queued' or status == 'running':                time.sleep(delay) # 等待一段时间后重试            else:                print(f"未知或错误状态: {status}. 报告数据: {json.dumps(report_data, indent=2)}")                return None # 其他非预期状态        except requests.exceptions.RequestException as e:            print(f"获取分析报告时发生请求错误: {e}")            return None        except json.JSONDecodeError:            print(f"无法解析API响应为JSON: {response.text}")            return None    print(f"达到最大重试次数 ({max_retries}),分析未完成。")    return None

完整示例代码

将上述两个步骤整合到一个函数中,可以实现完整的URL扫描和报告获取流程:

import requestsimport jsonimport timedef scan_url_and_get_report(scan_url, api_key, max_retries=10, delay=10):    """    提交URL到VirusTotal进行分析,并轮询获取最终报告。    """    # 步骤一:提交URL进行分析    submit_url_endpoint = "https://www.virustotal.com/api/v3/urls"    payload = { "url": scan_url }    headers = {        "accept": "application/json",        "x-apikey": api_key,    }    try:        response = requests.post(submit_url_endpoint, data=payload, headers=headers)        response.raise_for_status()        response_data = response.json()        analysis_id = response_data.get('data', {}).get('id', '')        if not analysis_id:            print(f"提交URL失败,未能获取分析ID。响应: {response.text}")            return None        print(f"URL '{scan_url}' 已提交,分析ID: {analysis_id}")    except requests.exceptions.RequestException as e:        print(f"提交URL时发生请求错误: {e}")        return None    except json.JSONDecodeError:        print(f"提交URL后无法解析API响应为JSON: {response.text}")        return None    # 步骤二:获取URL分析报告    report_endpoint_base = "https://www.virustotal.com/api/v3/analyses/"    headers = {        "accept": "application/json",        "x-apikey": api_key,    }    for i in range(max_retries):        try:            print(f"正在尝试获取报告 (第 {i+1}/{max_retries} 次尝试)...")            response = requests.get(f"{report_endpoint_base}{analysis_id}", headers=headers)            response.raise_for_status()            report_data = response.json()            status = report_data.get('data', {}).get('attributes', {}).get('status')            if status == 'completed':                print("分析完成,报告已获取。")                return report_data            elif status in ['queued', 'running']:                print(f"分析仍在进行中 (状态: {status}),等待 {delay} 秒后重试...")                time.sleep(delay)            else:                print(f"分析状态异常或未知: {status}. 报告数据: {json.dumps(report_data, indent=2)}")                return None        except requests.exceptions.RequestException as e:            print(f"获取分析报告时发生请求错误: {e}")            return None        except json.JSONDecodeError:            print(f"获取报告时无法解析API响应为JSON: {response.text}")            return None    print(f"达到最大重试次数 ({max_retries}),分析未完成或超时。")    return None# --- 使用示例 ---if __name__ == "__main__":    YOUR_API_KEY = "YOUR_VIRUSTOTAL_API_KEY" # <<<<<<< 请替换为您的VirusTotal API Key    TARGET_URL = "https://www.example.com/" # 替换为你想扫描的URL    if YOUR_API_KEY == "YOUR_VIRUSTOTAL_API_KEY":        print("请将 'YOUR_VIRUSTOTAL_API_KEY' 替换为您的实际API Key。")    else:        report = scan_url_and_get_report(TARGET_URL, YOUR_API_KEY)        if report:            print("n--- 完整分析报告 ---")            print(json.dumps(report, indent=2))            # 提取关键信息,例如检测结果            last_analysis_stats = report.get('data', {}).get('attributes', {}).get('last_analysis_stats', {})            print(f"n检测结果概览:")            print(f"  恶意: {last_analysis_stats.

以上就是VirusTotal API v3 URL扫描:正确获取分析报告的实践指南的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1371232.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
解决Streamlit应用中stqdm中断导致的冻结问题
上一篇 2025年12月14日 11:15:31
在VS Code中配置Python解释器优化模式的实践指南
下一篇 2025年12月14日 11:15:44

相关推荐

发表回复

登录后才能评论
关注微信