从网站中捕获视频流并保存到文件

7
对于我的图像分类项目,我需要收集分类图像,对我来说一个好的来源是在互联网上流传视频的不同网络摄像头。就像这个:

https://www.skylinewebcams.com/en/webcam/espana/comunidad-valenciana/alicante/benidorm-playa-poniente.html

我没有任何关于视频流和网络爬取的经验,所以在搜索了互联网上的信息之后,我用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文件为空),尽管在浏览器中视频流媒体工作良好。有人能向我解释如何将此视频流捕获到文件中吗?

2个回答

6

从那时起,我已经取得了一些进展。以下是代码:

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开发工具“网络”中浏览器发送的请求,只复制了最新的一个,它请求一些.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初始化流媒体传输。


这个项目有什么新消息吗?我有完全相同的情况。 - Swike

2
列表为空是因为您在没有头部的情况下进行了HTTP请求(这意味着您肯定是通过编程来实现的),大多数网站都会直接对此作出403响应。
您应该使用像Requests或pycurl这样的库来添加请求头,然后它们应该可以正常工作。如果您需要一个包含头部信息的示例请求,可以在观看流媒体时打开Web浏览器的开发人员控制台,找到m3u8 URL的HTTP请求,右键单击它,并选择“复制为cURL”。请注意,每个请求可能需要发送特定于站点的任意标头。
如果您想要爬取具有不同标题的多个站点,并且/或者希望为更改标题、地址或格式做好未来准备,则可能需要更高级的东西。最坏的情况是,您可能需要运行一个无头浏览器以WebDriver / Selenium打开站点并捕获它所生成的请求。
请记住,您可能必须阅读每个站点的ToS,否则您可能正在执行非法活动。违反ToS进行爬取基本上就是数字侵入,我认为至少Craigslist已经根据这一标准赢得了诉讼。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接