如何在没有界面显示的情况下抓取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浏览器的思路来解决这个问题

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线