[android] webview에서 html 콘텐츠를 얻는 방법?

웹뷰에서 html 코드를 얻는 가장 간단한 방법은 무엇입니까? 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");

}

}



답변

사실이 질문에는 많은 답이 있습니다. 그중 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을 잡을 수 있습니다. 가장 예쁜 방법은 아니지만 자바 스크립트 인터페이스가있을 때 다른 방법을 추가하여 수정할 수 있습니다.


  • 다른 방법은 거기 와 같은 HttpClient를 사용하는 입니다.

선택하는 옵션은 검색된 html로 무엇을 하려는지에 따라 달라집니다.


답변

KitKat 이상에서는 evaluateJavascriptwebview에서 메소드를 사용할 수 있습니다.

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
            }
    });

더 많은 예를 보려면 답변을 참조하십시오.


답변

Android 4.2의 경우 모든 javasscript 함수에 @JavascriptInterface를 추가하는 것을 잊지 마십시오.


답변

Android WebView는 Chrome 또는 FireFox와 같이 HTTP 서버에서 다운로드 한 HTML 콘텐츠를 렌더링하는 또 다른 렌더링 엔진입니다. WebView에서 렌더링 된 페이지 (또는 스크린 샷)를 가져와야하는 이유를 모르겠습니다. 대부분의 경우 이것은 필요하지 않습니다. 항상 HTTP 서버에서 직접 원시 HTML 콘텐츠를 가져올 수 있습니다.

HttpUrlConnection 또는 HttpClient를 사용하여 원시 스트림을 얻는 것에 대해 이미 게시 된 답변이 있습니다. 또는 Android에서 HTML 콘텐츠 파싱 / 프로세스를 처리 할 때 매우 편리한 라이브러리가 있습니다. JSoup , HTTP 서버에서 HTML 콘텐츠를 가져 오는 매우 간단한 API를 제공하고 HTML 파싱을 관리하는 데 도움이되는 HTML 문서의 추상 표현을 제공합니다. 좀 더 OO 스타일이지만 훨씬 쉽게 :

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

예를 들어 HTML 문서를 먼저 다운로드 한 다음 렌더링을 위해 WebView에 전달하기 전에 사용자 지정 CSS 또는 자바 스크립트를 추가하려는 경우에 편리합니다. 공식 웹 사이트에서 훨씬 더 많은 것을 확인할 가치가 있습니다.


답변

제자리에 배치해야하는 한 가지 터치 포인트는 Proguard 구성에서 “숨겨져”있습니다. HTML 리더는 앱을 디버깅 할 때 자바 스크립트 인터페이스를 통해 정상적으로 호출되지만, 다음과 같이 HTML 리더 기능이 Proguard 구성 파일에 선언되지 않는 한 Proguard를 통해 앱이 실행 되 자마자 더 이상 작동하지 않습니다.

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

Android 2.3.6, 4.1.1 및 4.2.1에서 테스트 및 확인되었습니다.


답변

Android에서는 보안 문제로이 작업을 수행 할 수 없습니다. 악의적 인 개발자는 사용자가 입력 한 로그인 정보를 매우 쉽게 훔칠 수 있습니다.

대신 웹보기에 표시되는 텍스트가 표시되기 전에 포착해야합니다. 응답 핸들러를 설정하고 싶지 않다면 (다른 답변에 따라) 인터넷 검색 으로이 수정을 찾았습니다.

URL url = new URL("/programming/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이 포함됩니다. 이 답변은 웹 페이지의 html을 Java의 문자열로 올바르게로드하는 가장 간단한 방법 이며 Android에서도 작동합니다. 나는 이것을 테스트하지 않았고 직접 작성하지 않았지만 도움이 될 수 있습니다.

또한이 URL은 하드 코딩되어 있으므로 변경해야합니다.


답변

먼저 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);
            }
}

이것은 대략 당신이 원하는 것을해야합니다. 그것은 WebView에서 HTML 코드를 가져 와서 https://stackoverflow.com/users/325081/aymon-fournier
외칠 수 있습니까?