将视频流从网站捕获到文件中

时间:2018-04-13 13:31:48

标签: python web-scraping video-streaming

对于我的图像分类项目,我需要收集分类图像,对我来说,一个很好的来源是世界各地的不同网络摄像头在互联网上流媒体视频。像这样:

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))

其中网址是从网站上的视频块来源获取的:

<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 个答案:

答案 0 :(得分:1)

此后我取得了一些进展。这是代码:

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(文件名,&#39; wb&#39;)中更改了&#39; w&#39;到&#39; wb&#39;写二进制数据,但最重要的是2)更改了url。我查看了Chrome devtools&#39; network&#39;浏览器发送什么请求来获取实时流,只是复制了最新的请求,它请求一些.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初始化流媒体,而无需在浏览器中打开页面。

答案 1 :(得分:1)

该列表显示为空,因为您正在发出不带标头的HTTP请求(这意味着您肯定是通过编程方式进行此操作),并且大多数站点只对403直接响应。

您应该使用Requests或pycurl之类的库向请求中添加标头,它们应该可以正常工作。对于示例请求(带有标头),您可以在观看流媒体时打开Web浏览器的开发人员控制台,找到m3u8 url的HTTP请求,右键单击它,然后“复制为cURL”。请注意,可能需要随每个请求一起发送特定于站点的任意标头。

如果您想抓取具有不同标题的多个站点,并且/或者希望将来对代码进行更改以防它们更改标题,地址或格式,那么您可能需要更高级的内容。最坏的情况是,您可能需要运行无头浏览器才能使用WebDriver / Selenium打开网站并捕获其发出的请求以生成请求。

请记住,您可能必须阅读每个站点的服务条款,否则可能正在执行非法活动。破坏ToS时进行报废基本上是数字入侵,我认为至少craigslist已经基于该标准赢得了诉讼。