如何在没有界面显示的情况下抓取HTTP的请求包
优采云 发布时间: 2021-06-29 19:09如何在没有界面显示的情况下抓取HTTP的请求包
简介
在前两篇文章中文章讲了如何抓HTTP请求包,包括代理服务器的使用和抓包方法。只是因为当前视频网站的视频地址不是在html页面直接获取的,所以视频是通过浏览器动态解释js脚本,然后向视频服务器发送视频请求来获取的。所以我们通过获取浏览器产生的HTTP请求来获取视频的下载地址。
直接使用 firefox 获取创意
我们想到了可以动态渲染js脚本的程序,最常见的就是浏览器。我们通过命令运行
firefox http://the.video.url
您可以使用 Firefox 打开 URL。但是我们不能不显示就这样使用,不过我们以后有办法解决这个问题。
python+selenium+Phantomjs
因为需要渲染没有界面显示的JS脚本,所以我们也想到了python+selenium+Phantomjs来动态渲染页面。 Phantomjs 是一个无头浏览器(Headless Browser 是一个没有界面的浏览器)。
但是Phantomjs1.5版本之后,不再支持flash插件。也就是说,Phantomjs 虽然可以动态加载 JS 脚本,但无法渲染视频。因此不会发出获取视频的 HTTP 请求。
我截图得到渲染后的页面,如下图:
视频播放窗口是黑色的,抓包程序无法捕获带有flv字符串的HTTP请求。
我也试过1.4.1版本的Phantomjs,网上说用这个命令可以加载Flash插件
./bin/phantomjs --load-plugins=yes examples/snap.js
通过渲染JS脚本,截图得到如下图:
虽然得到的截图和上图不同,但是视频中多了一个loading状态,但是我还是抓不到视频的HTTP请求。最后在python中调用webdriver.Phantomjs()时报错。
WebDriverException: Message: Can not connect to the Service phantomjs
最后不得不放弃使用 Phantomjs
slimerjs
我在网上搜索headless browser的时候,也发现了slimerjs。
PhantomJS 和 SlimerJS 的异同:来自文章
PhantomJS 基于 Webkit 内核,不支持 Flash 播放。 SlimerJS基于Firefox的Gecko内核,支持Flash播放,执行过程会有页面显示
正好我们需要支持Flash播放。但是问题又来了! SlimerJS 不是纯粹的 Headless 浏览器,它需要 DISPLAY! ! 那么我们可以做些什么来解决这个问题呢?有!
xvfb
xvfb 提供了一个类似于 X 服务器守护进程的环境和设置程序运行的环境变量 DISPLAY。
通过这个,上面提到的Firefox遇到的第一个问题也可以解决。感觉就像绕了一圈==!
计划实施
最后我们决定使用 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脚本中了。偶尔跑脚本的时候忘了加视频页面的path参数,很快就返回了。因为我的window.setTimeout()函数设置为10毫秒,为什么添加视频网页路径后还要等待90多秒呢?我打开firefox的firebug并打开那个网页。在加载所有请求后计算发现此函数的时间。下图是firebug的截图。
两个红色请求表示 90 秒后超时。这是计时器开始计时的时候,加上加载程序所需的时间,已经超过了 90 秒。
然后我们自然想到了在打开的页面之外写window.setTimeout()函数,设置返回的时间。
getPage.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浏览器的思路来解决这个问题