Какой самый быстрый способ очистить HTML-страницу в Android? - PullRequest
25 голосов
/ 04 июня 2010

Мне нужно извлечь информацию из неструктурированной веб-страницы в Android. Информация, которую я хочу, встроена в таблицу без идентификатора.

<table> 
<tr><td>Description</td><td></td><td>I want this field next to the description cell</td></tr> 
</table>

Должен ли я использовать

  • Pattern Matching?
  • Использовать BufferedReader для извлечения информации?

Или есть более быстрый способ получить эту информацию?

Ответы [ 6 ]

47 голосов
/ 21 июня 2010

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

Если предположить, что самый быстрый означает наиболее удобный, читаемый и поддерживаемый код, я предлагаю вам использовать DocumentBuilder для анализа соответствующего HTML-кода и извлечения данных с использованием XPathExpression s

Document doc = DocumentBuilderFactory.newInstance()
  .newDocumentBuilder().parse(new InputSource(new StringReader(html)));

XPathExpression xpath = XPathFactory.newInstance()
  .newXPath().compile("//td[text()=\"Description\"]/following-sibling::td[2]");

String result = (String) xpath.evaluate(doc, XPathConstants.STRING);

Если вам случится получить недопустимый HTML, я рекомендую изолировать соответствующую часть (например, используя substring(indexOf("<table")..) и при необходимости исправить оставшиеся ошибки HTML с помощью операций String перед анализом. Однако, если это становится слишком сложным (то есть очень плохо HTML), просто воспользуйтесь подходом хакерского сопоставления с шаблоном, как предложено в других ответах.

Примечания

  • XPath доступен начиная с уровня API 8 (Android 2.2). Если вы разрабатываете для более низких уровней API, вы можете использовать методы и условия DOM, чтобы перейти к узлу, который вы хотите извлечь
18 голосов
/ 18 июня 2010

Самый быстрый способ будет анализировать специфическую информацию самостоятельно. Вы, кажется, знаете структуру HTML точно заранее. Методы BufferedReader, String и StringBuilder должны быть достаточными. Вот начальный пример, который отображает первый абзац вашего собственного вопроса:

public static void main(String... args) throws Exception {
    URL url = new URL("http://stackoverflow.com/questions/2971155");
    BufferedReader reader = null;
    StringBuilder builder = new StringBuilder();
    try {
        reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
        for (String line; (line = reader.readLine()) != null;) {
            builder.append(line.trim());
        }
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
    }

    String start = "<div class=\"post-text\"><p>";
    String end = "</p>";
    String part = builder.substring(builder.indexOf(start) + start.length());
    String question = part.substring(0, part.indexOf(end));
    System.out.println(question);
}

Парсинг практически во всех случаях определенно быстрее сопоставления с шаблоном. Сопоставление с образцом проще, но существует определенный риск, что оно может привести к неожиданным результатам, особенно при использовании сложных шаблонов регулярных выражений.

Вы также можете использовать более гибкий сторонний анализатор HTML вместо того, чтобы писать его самостоятельно. Это будет не так быстро, как анализировать заранее известную информацию. Это, однако, будет более кратким и гибким. С приличными парсерами HTML разница в скорости незначительна. Я настоятельно рекомендую Jsoup для этого. Он поддерживает jQuery-подобные CSS-селекторы . Извлечение первого параграфа вашего вопроса будет так же просто, как:

public static void main(String... args) throws Exception {
    Document document = Jsoup.connect("http://stackoverflow.com/questions/2971155").get();
    String question = document.select("#question .post-text p").first().text();
    System.out.println(question);
}

Непонятно, о какой веб-странице вы говорите, поэтому я не могу привести более подробный пример того, как вы могли бы выбирать конкретную информацию на конкретной странице с помощью Jsoup. Если вы все еще не можете понять это самостоятельно, используя Jsoup и CSS-селекторы , то не стесняйтесь размещать URL-адрес в комментарии, и я предложу, как это сделать.

2 голосов
/ 19 июня 2010

Когда вы Scrap Html веб-страницы. Две вещи, которые вы можете сделать для этого. Первый использует REGEX. Еще один - HTML-парсеры.

Использование Regex не является предпочтительным для всех. Потому что это вызывает логическое исключение во время выполнения.

Использование Html Parser более сложно сделать. Вы не можете быть уверены, что будет получен правильный вывод. по моему опыту он тоже сделал исключение во время выполнения.

Так что лучше сделайте ответ URL в файл XML. и делать анализ XML очень легко и эффективно.

1 голос
/ 16 июня 2010

Почему бы тебе просто не написать

int start = data.indexOf ("Описание");

После этого возьмите необходимую подстроку.

0 голосов
/ 04 июня 2010

Один из способов сделать это - поместить html в строку, а затем вручную выполнить поиск и анализ строки. Если вы знаете, что теги будут располагаться в определенном порядке, вы сможете просмотреть их и найти данные. Это, однако, немного небрежно, так что вопрос в том, хотите ли вы, чтобы он работал сейчас ? или работа хорошо ?

int position = (String)html.indexOf("<table>");  //html being the String holding the html code
String field = html.substring(html.indexOf("<td>",html.indexOf("<td>",position)) + 4, html.indexOf("</td>",html.indexOf("</td>",position)));

как я и сказал ... очень неряшливо. Но если вы делаете это только один раз, и вам нужно, чтобы это работало, это может помочь.

0 голосов
/ 04 июня 2010

Почему бы вам не создать скрипт, который выполняет очистку с помощью cURL и простого html dom-парсера и просто получить нужное значение с этой страницы? Эти инструменты работают с PHP, но существуют другие инструменты для любого языка, который вам нужен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...