КОТ++
Прикладное программирование
Системное программирование
Программирование микроконтроллеров

Если вы дадите человеку программу, то займете его на один день. Если вы научите человека программировать, то займете его на всю жизнь. (с) Васим Латиф

Поиск по тегам

Опубликовано
Комментарии 0

Не так давно передо мной стояла серьёзная задача парсинга данных с некоторых сайтов. Проблема была в том, что обычный HTTP запрос не поможет, т.к. нужно, чтобы на странице отработал javascript и построил данные на странице, чтобы мы потом их спарсили. С помощью обычного HTTP запроса возвращается почти пустая страница. Выход очевиден - делать запрос через браузер, ждать пока отработают скрипты на странице и передавать исходный код уже сформированной страницы парсеру. Долго я гулял по гуглу прежде чем найти рабочее решение поставленной проблемы. Поэтому хочу поделиться с вами тем, что в итоге у меня получилось. Ниже привожу фрагменты кода с ключевыми моментами.
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
//нужно, чтобы загружалась полная версия сайта, а не мобильная
webView.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"); 
webView.setWebViewClient(new WebViewClient()    
{
    @Override
    public void onPageFinished(WebView view, String url)
    {
        webView.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+"
        + "document.getElementsByTagName('html')[0].innerHTML+'</html>');");
    }

    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
    {
        super.onReceivedError(view, errorCode, description, failingUrl);
    }

	@Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)
    {
        view.loadUrl(url);
        return true;
    }
});

private class MyJavaScriptInterface
{
    @JavascriptInterface
    public void processHTML(String html)
    {
        onPostExecute(html); 
        webView.stopLoading();
    }
}

public void execute()
{
    webView.loadUrl(url + urlQuery);
}
Методы execute и onPostExecute названы так, чтобы с получившимся классом можно было работать также как и с AsyncTask. Логика кода выше такая: браузер сообщает нам, что закончил свои дела по загрузке в событии onPageFinished, но теперь нам надо забрать исходный код страницы из браузера. Для этого прикручиваем JavaScriptInterface также как в коде выше. На stackoverflow.com находились различные вариации реализации этой хитрости, но почти ни один пример не работал. В каких-то тайных уголках гугла удалось найти решение и реализовать его, вот теперь делюсь хитрым приёмом с вами)

Теги , , ,
Автор