通过SlimerJS触发键盘事件使优酷视频快进(问题未解决)
来源:互联网 发布:μtorrent mac 编辑:程序博客网 时间:2024/05/02 02:36
需求
我想下载视频网站的视频,但是现在的视频网站不提供视频下载的链接。如果我们分析网页的源码,也许也不会发现视频的地址(网页源码太长,我没有分析过,我只是猜测网页中没有视频的链接)。
通过FireFox的FireBug工具,我能获得浏览器向视频服务器下载视频文件的请求,那么我们能不能用程序来获得这些视频文件的地址,然后自动化地下载它呢?答案是肯定的。
解决方案
我想通过SlimerJS打开一个视频网站,通过Python监听网卡的数据包,将所有HTTP请求截获下来,分析HTTP请求的请求头,将请求头带mp4,flv的请求路径截获下来,因为这些请求就是视频文件的请求。那我们可以用这些请求来获得视频。
我的前2篇博文已经讲解了原理,1.获取网页中的视频下载地址(利用抓包), 2.获取网页中的视频下载地址(用headless browser), 还有源码在github上,源码现在只是实现了一个tornado的服务器,来接受post过来的url,url是我们需要下载的视频的视频页面。tornado服务器收到请求后,会开一个线程,用SlimerJS打开那个视频页面,再开一个线程来监听网卡上的数据。用户下次再带着那个url请求访问tornado服务器,如果视频下载完成了就返回结果,否则返回In progress提示用户晚点再来。
改进方案
因为SlimerJS打开网页视频后,就任由其播放,播放速度较慢,我们需要等待视频播放完了才能将所有视频下载下来。如果我们的网络带宽够大,视频很快就缓冲好了,我们可以快进,让网页去缓冲后面的内容。那么我就想到了让SlimerJS去触发快进的事件。
通过观察,点击播放窗口后,可以按键盘的右箭头来进行快进。
问题
理想太丰满,现实很骨感。那么我们怎么来模拟键盘的右箭头呢?通过查SlimerJS(Phantomjs)的文档可以知道
var page = require("webpage").create()page.sendEvent("keypress", page.event.key.Right, null, null, null);
sendEvent
可以发送键盘事件,但是它发送的键盘事件是发送到document下的。元素监听的keydown事件都不会触发。
实验:
html页面如下
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <div id="divId" style="width: 200px; height: 200px; background-color: #0000cc" > <article> <p style="background-color: #1cc09f">hello</p> <p style="background-color: #1cc09f">hello</p> </article> </div> <a> aaaaaa <p>hello</p> </a> <input type="text" id="inputId" name=""></body><script src="./jquery.min.js"></script><script> $("div").click(function (e) { console.log('click div'); //alert("click div"); }); $("p").click(function (e) { console.log('click p'); //alert("click p"); //return false; // 使得div的点击事件消失 }); $(document).keydown(function(event){ console.log("doc keydown"); console.log(event.keyCode); }); $(document).keypress(function(event){ console.log("doc keypress"); console.log(event.keyCode); }); $("divId").keydown(function(){ console.log("div keydown") }); $("divId").keypress(function(){ console.log("div keypress") }); $("#inputId").keydown(function(event){ console.log("input keydown"); }); $("#inputId").keypress(function(event){ console.log("input keypress"); }); </script></html>
var page = require('webpage').create(); var videoUrl = "click_test.html" //上面的那个页面 page.open(videoUrl , function () {}//通过这个函数监听浏览器的控制台输出page.onConsoleMessage = function (msg) { console.log('Page console msg: ' + msg);};window.setInterval(function(){ page.sendEvent('keypress', page.event.key.Space, null, null, null); page.sendEvent('keydown', page.event.key.Space, null, null, null); console.log("page key press");}, 1000);
输出结果是:
...Page console msg: doc keypressPage console msg: 0Page console msg: doc keydownPage console msg: 32page key press...
我们回去看页面的脚本,我们可以发现我们监听的keypress事件有document,div,input这三个。但是只有document的事件被触发了。那么我们怎么让我们的子元素的keypress事件触发呢?
我们通过page.evaluate()函数来获取网页的元素,来触发元素的事件。
var page = require('webpage').create(); var videoUrl = "click_test.html" //上面的那个页面 page.open(videoUrl , function () { page.includeJs("jquery.min.js", function(){ window.setInterval(function(){ page.evaluate(function() { console.log("in evaluate function"); var ev = document.createEvent("KeyboardEvent"); ev.initKeyEvent("keydown", // typeArg, true, // canBubbleArg, true, // cancelableArg, null, // viewArg, Specifies UIEvent.view. This value may be null. false, // ctrlKeyArg, false, // altKeyArg, false, // shiftKeyArg, false, // metaKeyArg, 39, // keyCodeArg, 0); // charCodeArg); //document.querySelector("a").dispatchEvent(ev); document.getElementById('divId').dispatchEvent(ev); document.getElementById('inputId').dispatchEvent(ev); //page.sendEvent('keypress', page.event.key.Right, null, null, null); }); }, 5000); });});
输出的结果如下:
...Page console msg: in evaluate functionPage console msg: doc keydownPage console msg: 39Page console msg: input keydownPage console msg: doc keydownPage console msg: 39...
这里我对input,div这两个元素发送了keydown事件,但是,doc捕获了了2此,input捕获了一次。这是因为一般的div不能触发keydown事件。
对优酷视频网站触发快进事件
通过观察,打开优酷视频网站之后,点击右方向键,页面向右移动。鼠标点击视频之后,再点击右方向键,视频就可以快进了。
猜想
鼠标点击视频之后,focus到视频的元素,键盘事件传到视频元素,触发快进。
我将键盘事件发给这个flash播放器,可是没有效果。
document.getElementById('movie_player').dispatchEvent(ev);
到底是为什么呢?我查看了优酷的注册事件,键盘事件就那么4个
keydown:1.(function (t){t=t||B.event;var e=t.target||t.srcElement;a(e,t)})2.(function(t) { if (y.railslocked && 0 == y.page.maxh) return !0; t = t ? t : window.e; var e = y.getTarget(t); if (e && /INPUT|TEXTAREA|SELECT|OPTION/.test(e.nodeName)) { var n = e.getAttribute("type") || e.type || !1; if (!n || !/submit|button|cancel/i.tp) return !0 } if (l(e).attr("contenteditable")) return !0; if (y.hasfocus || y.hasmousefocus && !a || y.ispage && !a && !r) { var i = t.keyCode; if (y.railslocked && 27 != i) return y.cancelEvent(t); var o = t.ctrlKey || !1, s = t.shiftKey || !1, c = !1; switch (i) { case 38: case 63233: y.doScrollBy(72), c = !0; break; case 40: case 63235: y.doScrollBy(-72), c = !0; break; case 37: case 63232: y.railh && (o ? y.doScrollLeft(0) : y.doScrollLeftBy(72), c = !0); break; case 39: case 63234: y.railh && (o ? y.doScrollLeft(y.page.maxw) : y.doScrollLeftBy(-72), c = !0); break; case 33: case 63276: y.doScrollBy(y.view.h), c = !0; break; case 34: case 63277: y.doScrollBy(-y.view.h), c = !0; break; case 36: case 63273: y.railh && o ? y.doScrollPos(0, 0) : y.doScrollTo(0), c = !0; break; case 35: case 63275: y.railh && o ? y.doScrollPos(y.page.maxw, y.page.maxh) : y.doScrollTo(y.page.maxh), c = !0; break; case 32: y.opt.spacebarenabled && (s ? y.doScrollBy(y.view.h) : y.doScrollBy(-y.view.h), c = !0); break; case 27: y.zoomactive && (y.doZoom(), c = !0) } if (c) return y.cancelEvent(t) }})3.(function (t){var e=t.ctrlKey||!1;e&&(y.wheelprevented=!0)})keyup:(function (t){var e=t.ctrlKey||!1;e||(y.wheelprevented=!1)})
这里只有第2个函数详细一点,那我们仔细看看第二个函数的代码,可是也没有发现它监控如何处理快进的,只是处理了怎么去左右上下滑动。我现在就卡在如何触发快进的功能了!
如何触发快进功能是我接下来的需要实现的目标。
- 通过SlimerJS触发键盘事件使优酷视频快进(问题未解决)
- 关于键盘触发事件和屏幕触发事件的问题
- 关于键盘触发事件和屏幕触发事件的问题
- js键盘触发事件
- 键盘的触发事件
- 键盘事件触发自定义事件
- Js通过键盘控制键盘按下和松开触发事件
- 解决通过UIAlertView按钮点击事件pop回上级页面键盘会响应问题
- 解决视频文件播放不能快进问题
- html5获取键盘并设置触发事件,通过指定键添加事件
- javaScript键盘触发事件(仅个人学习)
- js通过keyCode值判断单击键盘上某个键,然后触发指定的事件
- 解决鼠标经过内部元素触发onmouseout事件的问题
- 解决input file文件chang事件只触发一次问题
- 解决长按手势两次触发事件的问题
- 【Unity3D自学记录】解决NGUI触发事件点透问题
- 解决动态生成input无法触发click事件的问题
- 解决动态生成input无法触发click事件的问题
- Vi/Vim查找替换使用方法
- 多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间
- Android之自定义view原来那么简单
- Nsis Script IfErrors判断失败
- IOS 学习笔记
- 通过SlimerJS触发键盘事件使优酷视频快进(问题未解决)
- 基于redisson的分布式锁的简单注解实现
- 【NOIP提高组】完美标号
- JAVA基础(1)——基本概念
- 基本算法练习五
- Eclipse设置文本格式为UTF-8/eclipse 工程平铺展开方式,如何将代码工程进行分类
- 编程规范_这个星球上最好的C编程风格
- 【POJ 2348】Euclid's Game 【简单博弈】
- Sublime Text 3 快捷键汇总