Как разобрать html из javafx webview и перенести эти данные в Jsoup Document? - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь проанализировать оглавление боковой панели (таблицы компонентов) некоторого сайта документации.

Jsoup

Я попробовал Jsoup. Я не могу получить элементы оглавления, потому что содержимое HTML в этом теге не является частью исходного HTML, но устанавливается JavaScript после загрузки страницы.

Вы можете увидеть мой предыдущий вопрос здесь: JSoup не может проанализировать дочерние элементы после глубины 2

Предлагаемое решение состоит в том, чтобы проверить, какие подключения выполняются вручную, из меню «Инструменты разработчика браузера» и найти последнюю версию веб-сайта. Анализ содержания боковой панели на некоторых сайтах документации - это только один из компонентов моей Java-программы, поэтому я не могу сделать это вручную.

JavaFX Webview (не Android Webview)

Я пробовал JavaFX Webview, потому что мне нужен браузер, который выполняет код JavaScript и заполняет компоненты тега Toc.

WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load("https://docs.microsoft.com/en-us/ef/ef6/");

Но я не знаю, как я могу получить HTML-код загруженного веб-сайта и перенести эти данные в Jsoup Document? Любой совет приветствуется.

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018
    WebView browser = new WebView();
    WebEngine webEngine = browser.getEngine();
    String url = "https://docs.microsoft.com/en-us/ef/ef6/";
    webEngine.load(url);
    //get w3c document from webEngine
    org.w3c.dom.Document w3cDocument = webEngine.getDocument();
    // use jsoup helper methods to convert it to string
    String html =  new org.jsoup.helper.W3CDom().asString(webEngine.get);
    // create jsoup document by parsing html
    Document doc = Jsoup.parse(url, html);
0 голосов
/ 17 сентября 2018

Я не могу обещать, что это лучший способ, так как я раньше не использовал Jsoup, и я не эксперт по XML API.

Класс org.jsoup.Jsoup имеет метод для анализа HTML в форме String: Jsoup.parse(String). Это означает, что нам нужно получить HTML из WebView как String. Класс WebEngine имеет свойство document , которое содержит org.w3c.dom.Document. Document - это HTML-содержимое текущей веб-страницы. Нам просто нужно преобразовать Document в String, что мы можем сделать с Transformer.

import java.io.StringWriter;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.jsoup.Jsoup;

public class Utils {

  private static Transformer transformer;

  // not thread safe
  public static org.jsoup.nodes.Document convert(org.w3c.dom.Document doc)
      throws TransformerException {
    if (transformer == null) {
      transformer = TransformerFactory.newDefaultInstance().newTransformer();
    }

    StringWriter writer = new StringWriter();
    transformer.transform(new DOMSource(doc), new StreamResult(writer));
    return Jsoup.parse(writer.toString());
  }

}

Вы будете вызывать это каждый раз, когда изменяется свойство document. Я провел несколько «тестов», просмотрев Google и напечатав org.jsoup.nodes.Document на консоли, и все, что кажется работает.

Однако есть одна оговорка; Насколько я понимаю, свойство document не меняется, когда происходят изменения на одной и той же веб-странице (однако сам Document может быть обновлен). Я не сетевой человек, так что извините, если я не вижу здесь смысла, но я считаю, что это включает в себя такие вещи, как фрейм, изменяющий его содержание. Может быть способ обойти это путем взаимодействия с JavaScript с помощью WebEngine.executeStript(String), но я не знаю как.

...