前言
博主平时爱看动漫,但是有些动漫需要会员才能看,于是博主打算写一个动漫网站的爬虫应用(github源码)来爬取动漫视频,这样就可以白嫖各种番剧了,嘿嘿;-) 但是这个爬虫做起来并不像我开始想的这么一帆风顺,爬视频源地址的时候遇到了问题,因为爬到的地址不是源地址,无法直接播放,所以只能退而求其次用WebView进行播放。但是播放页面有带颜色的广告,还在那里一弹一弹的,这肯定不能忍,于是就发展出了本文要讲的两种去除webView广告的思路。
正文
思路1:检索出网页的全部元素,只保留视频播放相关的元素(推荐)
思路2:根据className或id等属性值检索出需要去除的元素,并删除
思路1:
1.javascript代码:
在Assets/parser目录下创建一个js文件pureVideo.js,代码如下(目录可以自己diy):
javascript:window.customScript.getHtml('==========start===========');
var child = document.children;
window.customScript.getHtml('==========child size : ==========='+child.length);
var arr = [];
function fn(obj){
for(var i=0;i<obj.length;i++){
if(obj[i].children){
fn(obj[i].children);
}
arr.push(obj[i]);
}
}
fn(child);
window.customScript.getHtml('==========arr size : ==========='+arr.length);
for(var i=0;i<arr.length;i++){
var tagName = arr[i].tagName;
var id = arr[i].id;
var playerDiv = document.getElementsByClassName('player')[0];
if(tagName.indexOf('HTML') != -1 || tagName.indexOf('BODY') != -1
|| (tagName.indexOf('HEAD') != -1 && tagName.indexOf('HEADER') == -1)
|| id.indexOf('mobile-index') != -1 || arr[i].parentNode == playerDiv){
window.customScript.getHtml('========== jump index : ==========='+i);
continue;
}
var className = arr[i].className;
if(className == '' || (className.indexOf('player') == -1 && className.indexOf('playbox') == -1)
|| className.indexOf('-') != -1){
window.customScript.getHtml('==========remove element i : ==========='+i);
arr[i].parentNode.removeChild(arr[i]);
}
}
window.customScript.getHtml('==========finally --> arr size : ==========='+arr.length);
var html = document.getElementsByTagName('html')[0];
window.customScript.getHtml('html : '+html.innerHTML);
细节解析:
1.开头的javascript:必不可少,这是用来声明你这段字符串是js脚本;
2.arr数组是通过递归调用fn方法将所有元素都存到数组里;
3.window.customScript.getHtml()是我用来输出日志到AS logcat里的;
4.for循环里的两个判断,前面的判断用于排除掉你要保存下来的元素,后面的判断用于删掉你不需要的元素。里面用于判断的tagName和id等属性值在PC浏览器中用F12可以查看。如果你跟我一样需要用PC的浏览器查看手机端网页的html内容,请看这里。
警告:该文件里不要加任何忽略符号//,否则//后面和下面的代码均不会执行,我在这个大坑里躺了很久,你们千万不要步我的后尘!!!
2.在WebView页面使用上面的javascript脚本
在webView的webViewClient的onPageFinished回调中写入如下代码:
@Override
public void onPageFinished(WebView webView, String s) {
super.onPageFinished(webView, s);
try{
AssetManager assetManager = getAssets();
InputStream inputStream = assetManager.open("parser/pureVideo.js");
// InputStream inputStream = assetManager.open("parser/removeAds.js");
StringBuilder stringBuilder = new StringBuilder();
int len = 0;
byte[] buf = new byte[4096];
while((len=inputStream.read(buf))!=-1){
stringBuilder.append(new String(buf,0,len));
}
String js = stringBuilder.toString();
Log.d(TAG," js = "+js);
mWebView.loadUrl(js);
inputStream.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
细节解析:
1.通过AssetManager读取js文件的代码;
2.使用webView的loadUrl()方法调用js脚本;
思路2的js使用代码跟这个一样,讲思路2的时候就不贴代码了,改一下文件名就可以了。
3.输出日志流程:
1.创建内部类:
final class CustomScript{
@JavascriptInterface
public void getHtml(String html){
LogUtils.d(TAG+" html : \n"+html);
}
}
2.在初始化webView时把这个脚本类加入到webView脚本库中:
mWebView.addJavascriptInterface(new CustomScript(),"customScript");
然后你就可以像我那样在js代码里使用这个方法打印日志了。
思路2:
1.javascript代码:
javascript:window.customScript.getHtml('==========script test start===========');
var divList = document.getElementsByTagName('div');
window.customScript.getHtml('==========div size : ==========='+divList.length);
for(var i=0;i<divList.length;i++){
var className = divList[i].className;
window.customScript.getHtml('==========className : ==========='+className);
if(className == '' || (className.indexOf('player') == -1 && className.indexOf('playbox') == -1)
|| className.indexOf('-') != -1){
window.customScript.getHtml('==========remove div i : ==========='+i);
divList[i].parentNode.removeChild(divList[i]);
}
}
var headerList = document.getElementsByTagName('header');
window.customScript.getHtml('==========headerList size : ==========='+headerList.length);
for(var i=0;i<headerList.length;i++){
headerList[i].parentNode.removeChild(headerList[i]);
window.customScript.getHtml('==========remove header i : ==========='+i);
}
var bottomList = document.getElementsByClassName('bottom');
window.customScript.getHtml('==========bottomList size : ==========='+bottomList.length);
for(var i=0;i<bottomList.length;i++){
bottomList[i].parentNode.removeChild(bottomList[i]);
window.customScript.getHtml('==========remove bottom i : ==========='+i);
}
var h2List = document.getElementsByTagName('h2');
window.customScript.getHtml('==========h2List size : ==========='+h2List.length);
for(var i=0;i<h2List.length;i++){
h2List[i].parentNode.removeChild(h2List[i]);
window.customScript.getHtml('==========remove h2 i : ==========='+i);
}
var ulList = document.getElementsByTagName('ul');
window.customScript.getHtml('==========ulList size : ==========='+ulList.length);
for(var i=0;i<ulList.length;i++){
ulList[i].parentNode.removeChild(ulList[i]);
window.customScript.getHtml('==========remove ul i : ==========='+i);
}
window.customScript.getHtml('==========script test end===========');
结语
研究这个东西让我有种发现新大陆的感觉,因为通过上面的步骤你会发现,android和html、js等前端开发语言连接起来了,有了上面的思路应该可以搞很多的事情,大家可以发散一下脑洞~。~
使用过程中或者阅读过程中遇到问题欢迎下方留言。
如果文章有帮到你给个免费的赞和关注吧,这是我更新下去的动力,谢谢啦~。~!