通过SlimerJS触发键盘事件使优酷视频快进(问题未解决)

编程入门 行业动态 更新时间:2024-10-06 08:39:17

通过SlimerJS触发键盘事件使优酷视频<a href=https://www.elefans.com/category/jswz/34/1700055.html style=快进(问题未解决)"/>

通过SlimerJS触发键盘事件使优酷视频快进(问题未解决)

需求

我想下载视频网站的视频,但是现在的视频网站不提供视频下载的链接。如果我们分析网页的源码,也许也不会发现视频的地址(网页源码太长,我没有分析过,我只是猜测网页中没有视频的链接)。
通过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 keypress
Page console msg: 0
Page console msg: doc keydown
Page console msg: 32
page 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 function
Page console msg: doc keydown
Page console msg: 39
Page console msg: input keydown
Page console msg: doc keydown
Page 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触发键盘事件使优酷视频快进(问题未解决)

本文发布于:2024-02-14 11:28:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763050.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:快进   键盘   事件   视频   SlimerJS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!