要在Windows系统中通过ONVIF协议从网络摄像机获取实时截图,必须先让系统“认出”设备、建立安全通信、再调用标准接口触发快照动作——这三步缺一不可,跳过任一环节都会返回401未授权或503服务不可用错误。

确认摄像机已启用ONVIF并处于同一局域网
打开命令提示符,执行 ping 192.168.1.100(将IP替换为你摄像机的实际地址),确保能通;若失败,检查摄像机是否上电、网线是否插稳、电脑与摄像机是否在同一子网(如电脑IP为192.168.1.5,则摄像机应在192.168.1.x段)。
在浏览器中输入摄像机IP(如http://192.168.1.100),登录Web管理界面,在【网络】→【高级配置】→【ONVIF】中确认“启用ONVIF服务”已勾选,且端口为默认80或自定义端口(如8080);【务必关闭“仅允许HTTPS访问ONVIF”选项,否则Python或工具将无法建立SOAP连接】。
记下管理员用户名(如admin)和密码,后续所有ONVIF交互都依赖该凭据认证。
使用ONVIF Device Test Tool发现设备并验证截图能力
下载并安装官方ONVIF Device Test Tool(v2.4.0或更高),运行后点击【Discover Devices】按钮。
若列表为空:检查Windows防火墙是否阻止了UDP端口3702的入站/出站通信——需手动在“高级安全防火墙”中新建入站规则,协议类型选UDP,端口填3702,作用域设为“专用网络”。
设备出现后,双击它进入详情页 → 切换到【Media】标签 → 点击【GetProfiles】获取Profile Token(如“Profile_1”)→ 再点击【GetSnapshotUri】,输入该Token,点击执行。
若返回有效URL(形如rtsp://admin:12345@192.168.1.100:554/Streaming/Channels/1/picture或http://192.168.1.100/onvif/snapshot?profile=Profile_1),说明截图功能就绪;若报错“Not Implemented”,代表该摄像机固件不支持ONVIF快照,需改用RTSP拉流+帧提取方式。
用Python脚本直接调用ONVIF截图接口
方法一:使用requests库直取HTTP快照URL(最轻量,无需gSOAP)
用于设计、审查、生成或重构使用Effector、effector-react、Farfetched、AtomicRouter、@effector/next等库的React应用。
安装依赖:pip install requests
新建onvif_snapshot.py,粘贴以下代码(替换IP、端口、用户名、密码、Profile Token):
import requests
url = "http://192.168.1.100/onvif/snapshot?profile=Profile_1"
auth = ("admin", "12345")
resp = requests.get(url, auth=auth, timeout=5)
if resp.status_code == 200:
with open("snapshot.jpg", "wb") as f:
f.write(resp.content)
print("截图已保存")
else:
print(f"请求失败,状态码:{resp.status_code}")
注意:部分海康/大华设备需将URL中的/onvif/snapshot改为/ISAPI/Streaming/channels/101/picture,Token可省略;若返回401,确认Web界面中ONVIF用户权限是否包含“远程预览”。
方法二:用zeep库调用标准ONVIF MediaService接口(兼容性最强)
执行:pip install zeep
代码中关键行:snapshot_uri = media_service.GetSnapshotUri({"ProfileToken": "Profile_1"}) → 获取URI后,仍需用requests带认证GET该地址才能拿到图片二进制流。
这一步不能跳过认证:即使URI里含用户名密码,某些固件(如宇视IPC V3.0.0.R.20230915)会忽略URL参数,强制校验HTTP Basic Auth头。

















