Как получить html-контент из веб-представления?
Какой самый простой способ получить html-код из webview?
Я попробовал несколько методов из stackoverflow и google, но не могу найти точный метод. Пожалуйста, укажите точный способ.
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");
}
}
Ответы
Ответ 1
На самом деле у этого вопроса много ответов. Вот 2 из них:
- Это почти то же самое, что и у вас, я думаю, мы получили его из одного учебника.
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();
}
}
}
Таким образом, вы захватите html через javascript. Не самый красивый способ, но когда у вас есть интерфейс javascript, вы можете добавить другие методы, чтобы изменить его.
- Другим способом является использование HttpClient, например .
Выбор, который вы выбираете, также зависит, я думаю, от того, что вы намерены делать с извлеченным html...
Ответ 2
Для android 4.2, не забудьте добавить @JavascriptInterface ко всем функциям javasscript
Ответ 3
В KitKat и выше вы можете использовать метод 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
}
});
Подробнее см. .
Ответ 4
Android WebView - это еще один механизм рендеринга, который отображает содержимое HTML, загруженное с HTTP-сервера, подобно Chrome или FireFox. Я не знаю причину, по которой вам нужно получить отображаемую страницу (или скриншот) из WebView. Для большей части ситуации это необязательно. Вы всегда можете получить исходный HTML-контент с HTTP-сервера напрямую.
Уже есть ответы на вопрос о получении необработанного потока с использованием HttpUrlConnection или HttpClient. Кроме того, есть очень удобная библиотека при работе с анализом/обработкой HTML-контента на Android: JSoup, она предоставляет очень простой API для получения содержимого HTML из HTTP-сервера, и предоставить абстрактное представление HTML-документа, чтобы помочь нам управлять разбором HTML не только в более стиле OO, но и легко:
// Single line of statement to get HTML document from HTTP server.
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
Это удобно, когда, например, вы хотите сначала загрузить документ HTML, а затем добавить к нему пользовательский css или javascript, прежде чем передавать его в WebView для рендеринга. Гораздо больше на их официальном веб-сайте стоит проверить.
Ответ 5
Один момент, который я обнаружил, который должен быть установлен, "скрыт" в конфигурации Proguard. Хотя читатель HTML вызывает через интерфейс javascript просто отлично при отладке приложения, это больше не работает, как только приложение запускается через Proguard, если функция чтения HTML не объявлена в конфигурационном файле Proguard, например:
-keepclassmembers class <your.fully.qualified.HTML.reader.classname.here> {
public *;
}
Протестировано и подтверждено на Android 2.3.6, 4.1.1 и 4.2.1.
Ответ 6
Android не позволит вам сделать это для проблем безопасности. Злой разработчик может очень легко украсть введенные пользователем данные входа.
Вместо этого вы должны поймать текст, отображаемый в веб-представлении, до его отображения. Если вы не хотите настраивать обработчик ответа (в соответствии с другими ответами), я нашел это исправление с помощью некоторого googling:
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
будет содержать тот же html, нарисованный в веб-просмотре. Этот ответ от Простейший способ правильно загрузить html с веб-страницы в строку в Java, и он также должен работать на Android. Я не тестировал это и сам не писал, но это могло бы помочь вам.
Кроме того, URL-адрес, который вытягивает, является жестко запрограммированным, поэтому вам придется изменить это.
Ответ 7
Почему бы не сначала получить html, а затем передать его в веб-представление?
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);
}
}
Это примерно должно делать то, что вы хотите сделать. Он адаптирован из Возможно ли получить код HTML из WebView?
и закричите https://stackoverflow.com/users/325081/aymon-fournier за его ответ.
Ответ 8
Я бы предложил вместо того, чтобы пытаться извлечь HTML из WebView, вы извлекаете HTML из URL-адреса. Под этим я подразумеваю использование сторонней библиотеки, такой как JSoup, для прохождения HTML-кода для вас. Следующий код получит HTML-код из определенного URL-адреса для вас.
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;
}
Ответ 9
попробуйте использовать HttpClient, как сказал Sephy:
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;
}
Ответ 10
Простой для реализации. Просто нужно использовать javasript-методы в вашем html, чтобы получить значение 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);
}
}
}
Ваш Javascript в html
<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>
& Убедитесь, что вы вызываете callme, как показано ниже в html
<input name="FacadeAL" id="FacadeAL" type="text" size="5" onblur="callme()"/>
Надеюсь, это поможет вам.
Ответ 11
Я предлагаю попробовать какой-то подход Reflection, если у вас есть время потратить на отладчик
(извините, но у меня не было).
Начиная с метода loadUrl()
класса android.webkit.WebView
:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/webkit/WebView.java#WebView.loadUrl%28java.lang.String%2Cjava.util.Map%29
Вы должны приступить к android.webkit.BrowserFrame
, которые вызывают собственный метод nativeLoadUrl()
:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/webkit/BrowserFrame.java#BrowserFrame.nativeLoadUrl%28java.lang.String%2Cjava.util.Map%29
Реализация собственного метода должна быть здесь:
http://gitorious.org/0xdroid/external_webkit/blobs/a538f34148bb04aa6ccfbb89dfd5fd784a4208b1/WebKit/android/jni/WebCoreFrameBridge.cpp
Желаю удачи!
Ответ 12
выше приведены методы, если у вас есть веб-url, но если у вас есть локальный 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();
}