网页视频抓取脚本(怎么去抓取HTTP的请求包?(一)_)
优采云 发布时间: 2022-03-17 00:15网页视频抓取脚本(怎么去抓取HTTP的请求包?(一)_)
介绍
前两篇文章介绍了如何抓包HTTP请求包,包括代理服务器的使用和抓包方法。因为当前视频网站的视频地址不是直接在html页面上获取的,所以是通过浏览器动态解释js脚本获取视频,然后向视频服务器发送视频请求。所以我们通过获取浏览器生成的HTTP请求来获取视频的下载地址。
思路是直接用firefox
我们想到了可以动态渲染 js 脚本的程序,最常见的是浏览器。我们运行命令
firefox http://the.video.url
您可以使用 Firefox 打开 URL。但是没有显示我们是不能用的,不过后面我们有办法解决这个问题。
python+硒+Phantomjs
因为我们需要渲染JS脚本而不显示界面,所以我们也想到了python+selenium+Phantomjs来动态渲染页面。Phantomjs 是一个无头浏览器(无头浏览器是没有界面的浏览器)。
但是,在 Phantomjs 1.5 版本之后,不再支持 flash 插件。也就是说,虽然 Phantomjs 可以动态加载 JS 脚本,但不能渲染视频。因此,不会发出获取视频的 HTTP 请求。
我通过截图得到渲染后的页面,如下图:
视频播放窗口为黑色,抓包程序无法捕获带有flv字符串的HTTP请求。
我也试了1.4.1版本的Phantomjs,上面说可以通过这个命令加载Flash插件
./bin/phantomjs --load-plugins=yes 示例/snap.js
通过渲染JS脚本,截图得到如下图:
虽然得到的截图和上面的不一样,视频中有加载状态,但是我还是抓不到视频的HTTP请求。最后,在 python 中调用 webdriver.Phantomjs() 时出现错误。
WebDriverException: Message: Can not connect to the Service phantomjs
最后不得不放弃使用 Phantomjs
纤细的
当我在网上搜索headless browser时,我也发现了slimerjs。
PhantomJS 和 SlimerJS 的异同:来自这个文章
PhantomJS 基于 Webkit 内核,不支持 Flash 播放 SlimerJS 基于 Firefox 的 Gecko 内核,支持 Flash 播放,执行过程中会有页面显示
正是我们需要支持Flash播放。但是问题又来了!SlimerJS 不是纯粹的无头浏览器,它需要 DISPLAY!!. 那么我们能做些什么来解决这个问题呢?有!
xvfb
xvfb 通过提供类似于 X 服务器守护进程的环境变量 DISPLAY 并设置程序运行来为程序运行提供环境
通过这个,也可以解决前面提到的第一个火狐遇到的问题。我感觉我一直在一个圈子里= =!
方案实施
最后我们决定使用 slimerjs 来获取页面。因为没有办法通过python的selenium方法调用slimerjs,那么我们只能通过python调用命令行程序的方法来动态渲染页面。slimerjs 脚本如下。当我们调用这个脚本时,我们传入一个网页地址参数。slimerjs 负责打开这个页面并渲染页面的内容。
该脚本的文件名为 getPage.js
var page = require('webpage').create();
var videoUrl = phantom.args[0];
var page.open(videoUrl, function (){
window.setTimeout(function(){
phantom.exit();
},10);
});
我们python调用os.system("xvfb-run slimerjs getPage.js " + videoURL) 来渲染视频URL的视频。
我们最终的 Python 程序是 slimerjs_crawl_video.py
import os
import time
open163url = 'http://open.163.com/movie/2016/1/T/D/MBCRLBLRN_MBCRM7OTD.html'
startTime = time.time()
os.system("xvfb-run slimerjs getPage.js " + open163url)
print "use time: " + str(time.time() - startTime)
➜ capture_traffic sudo python pypcap_test.py
[sudo] password for honkee:
starting capture
mov.bn.netease.com/open-movie/nos/flv/2016/01/20/SBCRM4HFN_hd.flv
mov.bn.netease.com/open-movie/nos/flv/2016/01/20/SBCRM4HFN_hd.flv?start=107570066
获取视频地址!!
未解决的问题
调用 python slimerjs_crawl_video.py 时
➜ capture_traffic python slimerjs_craw_video.py
Vector smash protection is enabled.
use time: 94.3547639847
我仍然不知道如何控制这个时间。我尝试修改getPage.js的window.setTimeout函数的时间,但还是需要90多秒。我猜python的 os.system() 的限制是阻塞一段时间(90多秒)然后返回。接下来我会查一些相关的。
更新:
今天为了解决这个返回的问题,开始找这个问题的原因,直接找了os.system()函数的文档,说这个函数是阻塞的,等待执行命令在返回之前完成。那么问题应该出在 slimerjs 脚本中。不小心在运行脚本的时候忘记添加视频网页路径参数,很快就返回了。因为我的window.setTimeout()函数设置为10毫秒,那为什么我添加视频网页路径后还要等待90多秒,我打开firefox的firebug并打开了那个网页。在加载所有请求后计算发现此功能的时间。下图是萤火虫的截图。
直到两个红色请求后 90 秒后才指示超时。这是计时器开始计时的时间,加上程序加载所需的时间,超过 90 秒。
那么我们自然会想到在打开页面之外写window.setTimeout()函数,设置返回时间。
获取页面.js
var page = require('webpage').create();
var videoUrl = phantom.args[0];
window.setTimeout(function(){
phantom.exit();
},10000);
var page.open(videoUrl, function (){
window.setTimeout(function(){
phantom.exit();
},10);
});
最后发现这个标题不太适合这个文章。但是还是没变,因为我原来是按照headless browser的思路解决这个问题的