如何从 webview 获取 html 内容?

从 webview 获取 html 代码最简单的方法是什么? 我已经尝试了几种方法从堆栈溢出和谷歌,但无法找到一个确切的方法。请提到一个确切的方法。

public class htmldecoder extends Activity implements OnClickListener,TextWatcher
{
TextView txturl;
Button btgo;
WebView wvbrowser;
TextView txtcode;
ImageButton btcode;
LinearLayout llayout;
int flagbtcode;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.htmldecoder);


txturl=(TextView)findViewById(R.id.txturl);


btgo=(Button)findViewById(R.id.btgo);
btgo.setOnClickListener(this);


wvbrowser=(WebView)findViewById(R.id.wvbrowser);
wvbrowser.setWebViewClient(new HelloWebViewClient());
wvbrowser.getSettings().setJavaScriptEnabled(true);
wvbrowser.getSettings().setPluginsEnabled(true);
wvbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wvbrowser.addJavascriptInterface(new MyJavaScriptInterface(),"HTMLOUT");
//wvbrowser.loadUrl("http://www.google.com");
wvbrowser.loadUrl("javascript:window.HTMLOUT.showHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");




txtcode=(TextView)findViewById(R.id.txtcode);
txtcode.addTextChangedListener(this);


btcode=(ImageButton)findViewById(R.id.btcode);
btcode.setOnClickListener(this);


}


public void onClick(View v)
{
if(btgo==v)
{
String url=txturl.getText().toString();
if(!txturl.getText().toString().contains("http://"))
{
url="http://"+url;
}
wvbrowser.loadUrl(url);
//wvbrowser.loadData("<html><head></head><body><div style='width:100px;height:100px;border:1px red solid;'></div></body></html>","text/html","utf-8");
}
else if(btcode==v)
{
ViewGroup.LayoutParams params1=wvbrowser.getLayoutParams();
ViewGroup.LayoutParams params2=txtcode.getLayoutParams();
if(flagbtcode==1)
{
params1.height=200;
params2.height=220;
flagbtcode=0;
//txtcode.setText(wvbrowser.getContentDescription());
}
else
{
params1.height=420;
params2.height=0;
flagbtcode=1;
}
wvbrowser.setLayoutParams(params1);
txtcode.setLayoutParams(params2);


}
}


public class HelloWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {


view.loadUrl(url);
return true;
}
/*@Override
public void onPageFinished(WebView view, String url)
{
// This call inject JavaScript into the page which just finished loading.
wvbrowser.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}*/


}
class MyJavaScriptInterface
{
@SuppressWarnings("unused")
public void showHTML(String html)
{


txtcode.setText(html);
}
}


public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub


}


public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub


}


public void onTextChanged(CharSequence s, int start, int before, int count) {
wvbrowser.loadData("<html><div"+txtcode.getText().toString()+"></div></html>","text/html","utf-8");


}


}
247130 次浏览

事实上,这个问题有很多答案,以下是其中的两个:

  • 第一个和你的差不多,我想我们是从同一个教程中学到的。

public class TestActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
final WebView webview = (WebView) findViewById(R.id.browser);
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new MyJavaScriptInterface(this), "HtmlViewer");


webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
webview.loadUrl("javascript:window.HtmlViewer.showHTML" +
"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
}
});


webview.loadUrl("http://android-in-action.com/index.php?post/" +
"Common-errors-and-bugs-and-how-to-solve-avoid-them");
}


class MyJavaScriptInterface {


private Context ctx;


MyJavaScriptInterface(Context ctx) {
this.ctx = ctx;
}


public void showHTML(String html) {
new AlertDialog.Builder(ctx).setTitle("HTML").setMessage(html)
.setPositiveButton(android.R.string.ok, null).setCancelable(false).create().show();
}


}
}

这样你就可以通过 javascript 获取 html 了。这不是最好的方法,但是当你有了 javascript 接口,你可以添加其他方法来修补它。


  • 另一种方法是使用类似 那里的 HttpClient。

我认为,您选择的选项还取决于您打算如何处理检索到的 html..。

试着使用 HttpClient,正如赛菲所说:

public String getHtml(String url) {
HttpClient vClient = new DefaultHttpClient();
HttpGet vGet = new HttpGet(url);
String response = "";


try {
ResponseHandler<String> vHandler = new BasicResponseHandler();
response = vClient.execute(vGet, vHandler);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}

上面给出的方法是为如果你有一个网址,但是如果你有一个本地的 html,那么你也可以通过这个代码 html

AssetManager mgr = mContext.getAssets();
try {
InputStream in = null;
if(condition)//you have a local html saved in assets
{
in = mgr.open(mFileName,AssetManager.ACCESS_BUFFER);
}
else if(condition)//you have an url
{
URL feedURL = new URL(sURL);
in = feedURL.openConnection().getInputStream();}


// here you will get your html
String sHTML = streamToString(in);
in.close();


//display this html in the browser or web view




} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static String streamToString(InputStream in) throws IOException {
if(in == null) {
return "";
}


Writer writer = new StringWriter();
char[] buffer = new char[1024];


try {
Reader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));


int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}


} finally {


}


return writer.toString();
}

出于安全考虑,Android 不会让你这么做。邪恶的开发人员可以非常容易地窃取用户输入的登录信息。

相反,您必须在显示之前捕获在 webview 中显示的文本。如果你不想设置一个响应处理程序(根据其他答案) ,我在谷歌上找到了这个修复方法:

URL url = new URL("https://stackoverflow.com/questions/1381617");
URLConnection con = url.openConnection();
Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(con.getContentType());
/* If Content-Type doesn't match this pre-conception, choose default and
* hope for the best. */
String charset = m.matches() ? m.group(1) : "ISO-8859-1";
Reader r = new InputStreamReader(con.getInputStream(), charset);
StringBuilder buf = new StringBuilder();
while (true) {
int ch = r.read();
if (ch < 0)
break;
buf.append((char) ch);
}
String str = buf.toString();

这是很多代码,您应该能够复制/粘贴它,并且在它的结尾 str将包含在 webview 中绘制的相同 html。这个答案来自于 在 Java 中将 html 从网页正确加载到字符串中的最简单方法,它也可以在 Android 上工作。我没有测试这个,也没有自己写,但它可能会帮助你。

而且,这个提取的 URL 是硬编码的,所以您必须更改它。

为什么不首先获取 html,然后将其传递给 Web 视图?

private String getHtml(String url){
HttpGet pageGet = new HttpGet(url);


ResponseHandler<String> handler = new ResponseHandler<String>() {
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
String html;


if (entity != null) {
html = EntityUtils.toString(entity);
return html;
} else {
return null;
}
}
};


pageHTML = null;
try {
while (pageHTML==null){
pageHTML = client.execute(pageGet, handler);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return pageHTML;
}


@Override
public void customizeWebView(final ServiceCommunicableActivity activity, final WebView webview, final SearchResult mRom) {
mRom.setFileSize(getFileSize(mRom.getURLSuffix()));
webview.getSettings().setJavaScriptEnabled(true);
WebViewClient anchorWebViewClient = new WebViewClient()
{


@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);


//Do what you want to with the html
String html = getHTML(url);


if( html!=null && !url.equals(lastLoadedURL)){
lastLoadedURL = url;
webview.loadDataWithBaseURL(url, html, null, "utf-8", url);
}
}

这应该大致可以做您想要做的事情。它改编自 < a href = “ https://stackoverflow. com/questions/3479833/Is-It-could-to-get-the-HTML-code-from-WebView”> 有可能从 WebView 获得 HTML 代码吗 然后向 https://stackoverflow.com/users/325081/aymon-fournier喊出他的答案。

Android WebView 只是另一个呈现从 HTTP 服务器下载的 HTML 内容的渲染引擎,就像 Chrome 或 FireFox 一样。我不知道为什么你需要从 WebView 获得渲染页面(或截图)。在大多数情况下,这是没有必要的。您总是可以直接从 HTTP 服务器获得原始的 HTML 内容。

已经有人发布了关于使用 HttpUrlConnection 或 HttpClient 获取原始流的答案。另外,当处理 Android 上的 HTML 内容解析/处理时,有一个非常方便的库: JSoup,它提供非常简单的 API 来从 HTTP 服务器获取 HTML 内容,并提供 HTML 文档的抽象表示来帮助我们管理 HTML 解析,这不仅是一种更加面向对象的风格,而且非常容易:

// Single line of statement to get HTML document from HTTP server.
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();

例如,当您希望首先下载 HTML 文档,然后在将其传递到 WebView 进行呈现之前向其添加一些自定义 css 或 javascript 时,这种方法非常方便。在他们的官方网站上有更多的信息,值得一看。

它实现起来很简单只需要在你的 html 中使用 javasript 方法来获取 html 内容的值。 正如上面的代码一样,需要进行一些修改。

  public class htmldecoder extends Activity implements OnClickListener,TextWatcher
{
Button btsubmit; // this button in your xml file
WebView wvbrowser;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.htmldecoder);






btsubmit=(Button)findViewById(R.id.btsubmit);
btsubmit.setOnClickListener(this);


wvbrowser=(WebView)findViewById(R.id.wvbrowser);
wvbrowser.setWebViewClient(new HelloWebViewClient());
wvbrowser.getSettings().setJavaScriptEnabled(true);
wvbrowser.getSettings().setPluginsEnabled(true);
wvbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
MyJavaScriptInterface myinterface=new MyJavaScriptInterface();
wvbrowser.addJavascriptInterface(myinterface,"interface");
webView.loadUrl("file:///android_asset/simple.html");  //use one html file for //testing put your html file in assets. Make sure that you done JavaScript methods to get //values for html content in html file .
}
public void onClick(View v)
{
if(btsubmit==v)
{


webView.loadUrl("javascript:showalert()");// call javascript method.
//wvbr
}
}


final class MyJavaScriptInterface {






MyJavaScriptInterface() {


}


public void sendValueFromHtml(String value) {
System.out.println("Here is the value from html::"+value);
}


}


}

HTML 中的 Javascript

 <script type="text/javascript">
//<![CDATA[
var n1;
function callme(){
n1=document.getElementById("FacadeAL").value;
}
function showalert(){
window.interface.sendValueFromHtml(n1);// this method calling the method of interface which //you attached to html file in android. // & we called this showalert javasript method on //submmit buttton click of android.
}
//]]>
</script>

& 一定要打电话给我

<input name="FacadeAL" id="FacadeAL" type="text" size="5" onblur="callme()"/>
希望这个能帮到你。

我建议不要试图从 WebView 中提取 HTML,而是从 URL 中提取 HTML。我的意思是使用第三方库(如 JSoup)为您遍历 HTML。下面的代码将为您从特定的 URL 中获取 HTML

public static String getHtml(String url) throws ClientProtocolException, IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";


BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()
)
);


String line = null;
while ((line = reader.readLine()) != null){
result += line + "\n";
}
return result;
}

我发现需要放在适当位置的一个接触点是“隐藏”在 ProGuard 配置中。虽然 HTML 阅读器在调试应用程序时通过 javascript 界面调用是很好的,但是当应用程序通过 ProGuard 运行时,这种方法就不再起作用了,除非 HTML 阅读器函数是在 ProGuard 配置文件中声明的,如下所示:

-keepclassmembers class <your.fully.qualified.HTML.reader.classname.here> {
public *;
}

在 Android2.3.6、4.1.1和4.2.1上进行了测试和确认。

对于 android 4.2,不要忘记将@JavascriptInterface 添加到所有 javascript 函数中

在 KitKat 及以上版本中,您可以在 webview 中使用 evaluateJavascript方法

wvbrowser.evaluateJavascript(
"(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();",
new ValueCallback<String>() {
@Override
public void onReceiveValue(String html) {
Log.d("HTML", html);
// code here
}
});

有关更多示例,请参见 这个答案

with(webView) {
settings.javaScriptEnabled = true
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
view?.evaluateJavascript("document.documentElement.outerHTML") {
val html = it.replace("\\u003C", "<")
}
}
}
}