Android 使用JS注入获取网页视频链接

Android 使用JS注入获取网页视频链接

思路:
1、通过js注入获取整个网页html。
2、通过jsoup分析获取video播放器的数据源。

一、开启webviewjs功能,注入js回调

mWebView.addJavascriptInterface(new LocalAndroidObj(), "local_android_obj");// js 注入回调

二、通过jsoup 分析网页,使用方法类似jQuery语法。

    private class LocalAndroidObj{

        @JavascriptInterface
        public void showSource(String msg){
//            msg="<head>"+msg+"</head>";
            Log.i("TAG", "showSource: html:"+msg);
            Document parse = Jsoup.parse(msg);
            Elements video_source = parse.select("video source");// 分析网页
            if (video_source!=null){
                for (Element element : video_source) {
                    String src = element.attr("src");//提取链接
                    Log.i("TAG", "showSource: src:"+src);
                    if (onParseListener!=null){
                        onParseListener.onFindUrl(src);
                    }
                }
            }
        }

    }

三、页面初始化后执行js注入回调。

        @Override
        public void onPageFinished(final WebView view, String url) {
            super.onPageFinished(view, url);
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
//                    view.loadUrl("javascript:window.local_android_obj.showSource('<head>'+\" + \"document.getElementsByTagName('html')[0].innerHTML+'</head>');");
                    view.loadUrl("javascript:window.local_android_obj.showSource(document.getElementsByTagName('html')[0].outerHTML);");
//                    view.loadUrl("javascript:window.alert('jason');");
                }
            },100);
        }

完整代码:

package com.jasonliyihang.ffmpegvideoplayer;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.UiAutomation;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.CookieManager;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Administrator on 2018/3/22.
 */

public class ParseWebUrlHelper {
    private String mWebUrl;
    private Activity mActivity;
    private WebView mWebView;
    private OnParseWebUrlListener onParseListener;

    public static ParseWebUrlHelper getInstance() {
        return new ParseWebUrlHelper();
    }

    public ParseWebUrlHelper init(Activity act, ViewGroup viewGroup) {
        this.mActivity = act;
        this.mWebView = new WebView(mActivity);
        this.mWebView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        viewGroup.addView(this.mWebView);
        initWebSettings();
        return this;
    }

    public void free() {
        if (mWebView != null) {            //先从父容器中移除webview,然后再销毁webview
            try {
                ViewParent parent = mWebView.getParent();
                if (parent != null) {
                    ((ViewGroup) parent).removeView(mWebView);
                }
                mWebView.stopLoading();            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
                mWebView.getSettings().setJavaScriptEnabled(false);
                mWebView.clearHistory();
                mWebView.clearCache(true);
                mWebView.removeAllViews();
                mWebView.destroy();
                mWebView = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initWebSettings() {
        WebView mWebView = this.mWebView;
        mWebView.clearFocus();
        WebSettings mWebSettings = mWebView.getSettings();
        mWebSettings.setJavaScriptEnabled(true);
        mWebSettings.setDefaultTextEncodingName("utf-8");
        mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        mWebSettings.setDisplayZoomControls(false);
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setAllowFileAccess(true);
        mWebSettings.setAllowContentAccess(true);
        mWebSettings.setSupportZoom(true);
        mWebSettings.setAllowContentAccess(true);
        mWebSettings.setLoadWithOverviewMode(true);
        mWebSettings.setBuiltInZoomControls(true);// 隐藏缩放按钮
        mWebSettings.setUseWideViewPort(true);// 可任意比例缩放
        mWebSettings.setLoadWithOverviewMode(true);// setUseWideViewPort方法设置webview推荐使用的窗口。setLoadWithOverviewMode方法是设置webview加载的页面的模式。
        mWebSettings.setSaveFormData(true);// 保存表单数据
        mWebSettings.setJavaScriptEnabled(true);
        mWebSettings.setTextZoom(100);
        mWebSettings.setDomStorageEnabled(true);
        mWebSettings.setSupportMultipleWindows(true);// 新加//我就是没有这一行,死活不出来。MD,硬是没有人写这一句!
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        mWebSettings.setMediaPlaybackRequiresUserGesture(true);
        mWebSettings.setAllowFileAccessFromFileURLs(true);
        mWebSettings.setAllowUniversalAccessFromFileURLs(true);
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        mWebSettings.setLoadsImagesAutomatically(true);
        mWebSettings.setAppCacheEnabled(true);
        mWebSettings.setAppCachePath(mActivity.getCacheDir().getAbsolutePath());
        mWebSettings.setDatabaseEnabled(true);
        mWebSettings.setGeolocationDatabasePath(mActivity.getDir("database", 0).getPath());
        mWebSettings.setGeolocationEnabled(true);
        CookieManager instance = CookieManager.getInstance();
        instance.setAcceptCookie(true);
        if (Build.VERSION.SDK_INT >= 21) {
            instance.setAcceptThirdPartyCookies(mWebView, true);
        }
        mWebView.setWebViewClient(new MyWebViewClient());
        mWebView.setWebChromeClient(new GoogleWeb());
        mWebView.addJavascriptInterface(new LocalAndroidObj(), "local_android_obj");// js 注入回调
        enabledCookie(this.mWebView);//启用cookie
    }

    public ParseWebUrlHelper setLoadUrl(String url) {
        this.mWebUrl = url;
        return this;
    }

    public ParseWebUrlHelper startParse() {
        mWebView.loadUrl(this.mWebUrl);
        return this;
    }

    /*启用cookie*/
    private void enabledCookie(WebView web) {
        CookieManager instance = CookieManager.getInstance();
        instance.setAcceptCookie(true);
        if (Build.VERSION.SDK_INT >= 21) {
            instance.setAcceptThirdPartyCookies(web, true);
        }
    }

    public ParseWebUrlHelper setOnParseListener(OnParseWebUrlListener onParseListener) {
        this.onParseListener = onParseListener;
        return this;
    }


    private class GoogleWeb extends WebChromeClient {

    }

    private class LocalAndroidObj{

        @JavascriptInterface
        public void showSource(String msg){
//            msg="<head>"+msg+"</head>";
            Log.i("TAG", "showSource: html:"+msg);
            Document parse = Jsoup.parse(msg);
            Elements video_source = parse.select("video source");// 分析网页
            if (video_source!=null){
                for (Element element : video_source) {
                    String src = element.attr("src");//提取链接
                    Log.i("TAG", "showSource: src:"+src);
                    if (onParseListener!=null){
                        onParseListener.onFindUrl(src);
                    }
                }
            }
        }

    }

    private class MyWebViewClient extends WebViewClient {


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            if (request.getUrl().toString().startsWith("intent") || request.getUrl().toString().startsWith("youku")) {
                return true;
            } else {
                return super.shouldOverrideUrlLoading(view, request);
            }
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.startsWith("intent") || url.startsWith("youku")) {
                return true;
            } else {
                return super.shouldOverrideUrlLoading(view, url);
            }
        }

        /*解决ssl证书问题*/
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }


        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                String url = request.getUrl().toString();
//                onParseListener.onFindUrl(url);
            }
            return super.shouldInterceptRequest(view, request);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            startCount();//加载超时处理
        }

        @Override
        public void onPageFinished(final WebView view, String url) {
            super.onPageFinished(view, url);
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
//                    view.loadUrl("javascript:window.local_android_obj.showSource('<head>'+\" + \"document.getElementsByTagName('html')[0].innerHTML+'</head>');");
                    view.loadUrl("javascript:window.local_android_obj.showSource(document.getElementsByTagName('html')[0].outerHTML);");
//                    view.loadUrl("javascript:window.alert('jason');");
                }
            },100);
        }

    }

    private void startCount() {
        final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                onParseListener.onError("解析视频超时,请检查网速或网络是否出现问题...");
                timer.cancel();
                timer.purge();
            }
        };
        int timeOut = 20 * 1000;
        timer.schedule(timerTask, timeOut, 1);
    }

    public interface OnParseWebUrlListener {

        void onFindUrl(String url);

        void onError(String errorMsg);

    }
}


测试代码:

        //初始化
        parseWebUrlHelper = ParseWebUrlHelper.getInstance().init(this, frameLayout);
        parseWebUrlHelper.setLoadUrl("https://www.w3school.com.cn/html5/html_5_video_dom.asp");
        //解析网页中视频
        parseWebUrlHelper.setOnParseListener(new ParseWebUrlHelper.OnParseWebUrlListener() {
            @Override
            public void onFindUrl(String url) {
                Log.i("TAG", "onFindUrl: media url "+url);
            }

            @Override
            public void onError(String errorMsg) {

            }
        });
        parseWebUrlHelper.startParse();

如果对你有帮助请点赞 谢谢!!

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值