在Android中抓取HTML网页的最快方法是什么?

时间:2010-06-04 02:33:13

标签: android html web-scraping

我需要从Android中的非结构化网页中提取信息。我想要的信息嵌入在没有id的表中。

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

我应该使用

  • 模式匹配?
  • 使用BufferedReader提取信息吗?

或者有更快的方法来获取这些信息吗?

6 个答案:

答案 0 :(得分:47)

我认为在这种情况下,寻找快速方式提取信息是没有意义的,因为答案中已建议的方法几乎没有性能差异当你将它与下载 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")..),并在解析之前使用String操作纠正剩余的HTML错误。如果这变得过于复杂(即非常糟糕的 HTML),请按照其他答案中的建议采用hacky模式匹配方法。

<强>说明

  • XPath自API Level 8(Android 2.2)开始提供。如果您针对较低的API级别进行开发,则可以使用DOM方法和条件导航到要提取的节点

答案 1 :(得分:18)

最快方式将自行解析特定的信息。您似乎事先已经准确地了解了HTML结构。 BufferedReaderStringStringBuilder方法就足够了。这是一个启动示例,显示您自己问题的第一段:

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-like CSS selectors。提取问题的第一段将非常简单:

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 selectors自行计算,请随时在评论中发布该网址,我会建议如何操作。

答案 2 :(得分:2)

当您报废Html网页时。你可以做两件事。 First One正在使用REGEX。另一个是Html解析器。

使用正则表达式并非所有人都喜欢。因为它在运行时导致逻辑异常。

使用Html Parser更加复杂。你不能确定会有适当的输出。根据我的经验,它也造成了一些运行时异常。

所以最好让url对Xml文件做出响应。而且xml parsing非常简单有效。

答案 3 :(得分:1)

你为什么不写

int start = data.indexOf(“Description”);

之后获取所需的子字符串。

答案 4 :(得分:0)

为什么不创建一个使用cURL和simple html dom parser 进行抓取的脚本,只需从该页面获取所需的值?这些工具适用于PHP,但是存在适用于您需要的任何语言的其他工具。

答案 5 :(得分:0)

这样做的一种方法是将html放入String中,然后手动搜索并解析String。如果您知道标签将按特定顺序排列,那么您应该能够抓取它并查找数据。然而,这有点草率,所以它是一个问题,你想让它工作现在?或者

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)));
像我说的那样......真的很草率。但是,如果你只是这样做一次而你需要它才能发挥作用,那么这就可以解决问题了。