从网站捕获视频流到文件中
Capturing the video stream from a website into a file
对于我的图像分类项目,我需要收集分类图像,对我来说,一个好的来源是互联网上世界各地的不同网络摄像头流视频。喜欢这个:
我对视频流和网络抓取一般没有任何经验,所以在互联网上搜索信息后,我在 python 中想出了这个天真的代码:
url='https://www.skylinewebcams.com/a816de08-9805-4cc2-94e6-2daa3495eb99'
r1 = requests.get(url, stream=True)
filename = "stream.avi"
if(r1.status_code == 200):
with open(filename,'w') as f:
for chunk in r1.iter_content(chunk_size=1024):
f.write(chunk)
else:
print("Received unexpected status code {}".format(r.status_code))
url 地址取自网站视频块的来源:
<video data-html5-video=""
poster="//static.skylinewebcams.com/_2933625150.jpg" preload="metadata"
src="blob:https://www.skylinewebcams.com/a816de08-9805-4cc2-94e6-
2daa3495eb99"></video>
但它不起作用(avi 文件为空),即使在浏览器中视频流运行良好。任何人都可以向我解释如何将此视频流捕获到文件中吗?
从那时起我取得了一些进步。这是代码:
print ("Recording video...")
url='https://hddn01.skylinewebcams.com/02930601ENXS-1523680721427.ts'
r1 = requests.get(url, stream=True)
filename = "stream.avi"
num=0
if(r1.status_code == 200):
with open(filename,'wb') as f:
for chunk in r1.iter_content(chunk_size=1024):
num += 1
f.write(chunk)
if num>5000:
print('end')
break
else:
print("Received unexpected status code {}".format(r.status_code))
现在我可以得到一些写入文件的视频。我所做的更改是 1) 在 open(filename,'wb') 中将 'w' 更改为 'wb' 以写入二进制数据,但最重要的 2) 已更改 url。我查看了 Chrome devtools 'network' 浏览器发送了哪些请求来获取实时流,并且只是复制了最新鲜的一个,它请求一些 .ts 文件。
接下来,我找到了如何获取.ts 视频文件的地址。可以像这样使用 m3u8 模块(可通过 pip 安装):
import m3u8
m3u8_obj = m3u8.load('https://hddn01.skylinewebcams.com/live.m3u8?
a=k2makj8nd279g717kt4d145pd3')
playlist=[el['uri'] for el in m3u8_obj.data['segments']]
视频文件的播放列表将是这样的
['https://hddn04.skylinewebcams.com/02930601ENXS-1523720836405.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720844347.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720852324.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720860239.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720868277.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720876252.ts']
我可以从列表中下载每个视频文件。
剩下的唯一问题是,为了加载播放列表,我需要先在浏览器中打开网页。否则播放列表将是空的。可能打开网页会启动流式传输,这会在可以请求的服务器上创建 m3u8 文件。我仍然不知道如何在不在浏览器中打开页面的情况下从 python 初始化流式传输。
该列表结果为空,因为您正在发出没有 headers 的 HTTP 请求(这意味着您肯定是以编程方式进行的)并且大多数网站直接响应带有 403 的网站。
您应该使用 Requests 或 pycurl 等库将 headers 添加到您的请求中,它们应该可以正常工作。对于示例请求(完成 headers),您可以在观看流式传输时打开 Web 浏览器的开发人员控制台,找到一个针对 m3u8 url、right-click 的 HTTP 请求,然后 "copy as cURL"。请注意,可能需要随每个请求一起发送 site-specific,任意 headers。
如果您想抓取具有不同 headers 的多个站点,and/or 想要 future-proof 您的代码以防他们更改 headers、地址或格式,然后您可能需要更高级的东西。 Worst-case 场景,您可能需要 运行 无头浏览器以使用 WebDriver/Selenium 打开网站并捕获它发出的请求以生成您的请求。
请记住,您可能必须阅读每个站点的服务条款,否则您可能会从事非法活动。在违反服务条款的情况下进行抓取基本上是数字侵入,我认为至少 craigslist 已经根据该标准赢得了诉讼。
对于我的图像分类项目,我需要收集分类图像,对我来说,一个好的来源是互联网上世界各地的不同网络摄像头流视频。喜欢这个:
我对视频流和网络抓取一般没有任何经验,所以在互联网上搜索信息后,我在 python 中想出了这个天真的代码:
url='https://www.skylinewebcams.com/a816de08-9805-4cc2-94e6-2daa3495eb99'
r1 = requests.get(url, stream=True)
filename = "stream.avi"
if(r1.status_code == 200):
with open(filename,'w') as f:
for chunk in r1.iter_content(chunk_size=1024):
f.write(chunk)
else:
print("Received unexpected status code {}".format(r.status_code))
url 地址取自网站视频块的来源:
<video data-html5-video=""
poster="//static.skylinewebcams.com/_2933625150.jpg" preload="metadata"
src="blob:https://www.skylinewebcams.com/a816de08-9805-4cc2-94e6-
2daa3495eb99"></video>
但它不起作用(avi 文件为空),即使在浏览器中视频流运行良好。任何人都可以向我解释如何将此视频流捕获到文件中吗?
从那时起我取得了一些进步。这是代码:
print ("Recording video...")
url='https://hddn01.skylinewebcams.com/02930601ENXS-1523680721427.ts'
r1 = requests.get(url, stream=True)
filename = "stream.avi"
num=0
if(r1.status_code == 200):
with open(filename,'wb') as f:
for chunk in r1.iter_content(chunk_size=1024):
num += 1
f.write(chunk)
if num>5000:
print('end')
break
else:
print("Received unexpected status code {}".format(r.status_code))
现在我可以得到一些写入文件的视频。我所做的更改是 1) 在 open(filename,'wb') 中将 'w' 更改为 'wb' 以写入二进制数据,但最重要的 2) 已更改 url。我查看了 Chrome devtools 'network' 浏览器发送了哪些请求来获取实时流,并且只是复制了最新鲜的一个,它请求一些 .ts 文件。
接下来,我找到了如何获取.ts 视频文件的地址。可以像这样使用 m3u8 模块(可通过 pip 安装):
import m3u8
m3u8_obj = m3u8.load('https://hddn01.skylinewebcams.com/live.m3u8?
a=k2makj8nd279g717kt4d145pd3')
playlist=[el['uri'] for el in m3u8_obj.data['segments']]
视频文件的播放列表将是这样的
['https://hddn04.skylinewebcams.com/02930601ENXS-1523720836405.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720844347.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720852324.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720860239.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720868277.ts',
'https://hddn04.skylinewebcams.com/02930601ENXS-1523720876252.ts']
我可以从列表中下载每个视频文件。
剩下的唯一问题是,为了加载播放列表,我需要先在浏览器中打开网页。否则播放列表将是空的。可能打开网页会启动流式传输,这会在可以请求的服务器上创建 m3u8 文件。我仍然不知道如何在不在浏览器中打开页面的情况下从 python 初始化流式传输。
该列表结果为空,因为您正在发出没有 headers 的 HTTP 请求(这意味着您肯定是以编程方式进行的)并且大多数网站直接响应带有 403 的网站。
您应该使用 Requests 或 pycurl 等库将 headers 添加到您的请求中,它们应该可以正常工作。对于示例请求(完成 headers),您可以在观看流式传输时打开 Web 浏览器的开发人员控制台,找到一个针对 m3u8 url、right-click 的 HTTP 请求,然后 "copy as cURL"。请注意,可能需要随每个请求一起发送 site-specific,任意 headers。
如果您想抓取具有不同 headers 的多个站点,and/or 想要 future-proof 您的代码以防他们更改 headers、地址或格式,然后您可能需要更高级的东西。 Worst-case 场景,您可能需要 运行 无头浏览器以使用 WebDriver/Selenium 打开网站并捕获它发出的请求以生成您的请求。
请记住,您可能必须阅读每个站点的服务条款,否则您可能会从事非法活动。在违反服务条款的情况下进行抓取基本上是数字侵入,我认为至少 craigslist 已经根据该标准赢得了诉讼。