日前遇到了这么一个需求,用WebView去加载url,在WebView 页面加载成功后,提取页面的内容。在页面加载完成再提取,就需要设置WebViewClient对象,重写 里面的的方法:
client = new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.e("webview", "shouldOverrideUrlLoading: "+request.toString() );
return super.shouldOverrideUrlLoading(view, request);
}
@Override
public void onPageFinished(WebView view, String url) {
Log.e("webview", "onPageFinished: "+url );
view.loadUrl("javascript:window.local_obj.showSource('<head>'+" +
"document.getElementsByTagName('html')[0].innerHTML+'</head>');");
super.onPageFinished(view, url);
}
};
webView.setWebViewClient(client);
上面代码在 onPageFinished (页面加载完成)里面执行了一个loadUrl 方法,去获取页面内容,loadUrl 里面的内容,既然用到了JS则需要设置 webview 支持JS语法的使用: webView.getSettings().setJavaScriptEnabled(true);
同时 我们用js获取内容后 如何在JAVA 成展现呢,WebView 需要设置 接口:
webView.addJavascriptInterface(new JS(context),"local_obj");
在 设置WebView 支持JS 添加 映射接口时,还需要添加注释,否者可能获取不到HTML数据
@SuppressLint({"JavascriptInterface","SetJavaScriptEnabled","AddJavascriptInterface"})
通过这个方法就可以将JS成调用的方法 映射到JAVA成的方法里面,而后面的 local_obj,就是loadUrl 用的的全局的一个对象来获取HTML 内容,来看看JAVA 层 JS 这个类的是如何实现的:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class JS {
Context context;
Pattern pattern;
Matcher matcher;
ClipboardManager cm;
ClipData clipData;
public JS(Context context) {
this.context = context;
cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
@JavascriptInterface
@SuppressWarnings("unused")
public void showSource(String html){
Log.e("html",html);
getMesg(html);
}
}
JS类很简单就一个final 类 里面一个方法 接受 获取的HTML、内容,但是要注意到有一个注解 @JavascriptInterface,这个注解说明这个是和Js 的通信接口,在Js中可以调用这个获取HTML内容,我们在这个方法里做一些提取操作。
再来看下 onPageFinish 里面使用的loadUrl 里面的内容:
"javascript:window.local_obj.showSource('<head>'+" +
"document.getElementsByTagName('html')[0].innerHTML+'</head>');"
javascript:说明调用 js方法,而这个方法我们看的很眼熟:local_obj.showSource ,其实这个就是我们JAVA成定义的JS类里面的内容,而window. 这个是JS里面一个全局的操作,这里不做多讲解,而 这个方法里面的也是Js提取标签内容的一个Js语法操作,至此 WebView 提取HTML的内容就结束了。这里贴出完整的代码
@SuppressLint({"JavascriptInterface","SetJavaScriptEnabled","AddJavascriptInterface"})
void initWebView(){
webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JS(context),"local_obj");
client = new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.e("webview", "shouldOverrideUrlLoading: "+request.toString() );
return super.shouldOverrideUrlLoading(view, request);
}
@Override
public void onPageFinished(WebView view, String url) {
Log.e("webview", "onPageFinished: "+url );
view.loadUrl("javascript:window.local_obj.showSource('<head>'+" +
"document.getElementsByTagName('html')[0].innerHTML+'</head>');");
super.onPageFinished(view, url);
}
};
webView.setWebViewClient(client);
}
public final class JS {
Context context;
Pattern pattern;
Matcher matcher;
ClipboardManager cm;
ClipData clipData;
public JS(Context context) {
this.context = context;
cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
@JavascriptInterface
@SuppressWarnings("unused")
public void showSource(String html){
Log.e("html",html);
getMesg(html);
}
public void getMesg(String html){
String patterns = "<pre style=\"word-wrap: break-word; white-space: pre-wrap;\">(.*?)</pre>";
pattern = Pattern.compile(patterns);
matcher = pattern.matcher(html);
if (matcher.find()){
clipData = ClipData.newPlainText("Label",matcher.group(1));
cm.setPrimaryClip(clipData);
}
}
}