0

我正在构建一个简单的新闻阅读器应用程序,并且正在使用 HTMLCleaner 来检索和解析数据。我已经成功地使用 HTMLCleaner 的命令行版本和使用 xmllint 获得了我需要的数据,例如:

java -jar htmlcleaner-2.6.jar src=http://www.reuters.com/home nodebyxpath=//div[@id=\"topStory\"]

curl www.reuters.com | xmllint --html --xpath //div[@id='"topStory"'] -

两者都返回我想要的数据。然后,当我尝试在我的代码中使用 HTMLCleaner 发出这个请求时,我没有得到任何结果。更令人不安的是,即使是基本查询,比如//div在我的应用程序中只返回 8 个节点,而命令行报告 70+,这是正确的。

这是我现在拥有的代码。它在一个扩展的 Android 类中,AsyncTask因此它在后台执行。最终代码实际上会得到我需要的文本数据,但我很难让它返回结果。当我记录标题节点时,节点计数为零。

我已经尝试了各种方式来转义 xpath 查询字符串,但没有任何区别。HTMLCleaner 代码位于我项目的单独源文件夹中,并且(至少我认为)与我的应用程序的其余部分一起编译为 dalvik,因此不兼容的 jar 文件不应该是问题。

我试图转储 HTMLCleaner 文件,但它不适用于 LogCat,并且当我转储它时缺少很多页面标记,这让我认为 HTMLCleaner 解析不正确并丢弃了大部分页面,但那怎么可能命令行版本工作正常的情况?

此外,该应用程序不会崩溃,我没有记录任何异常。

protected Void doInBackground(URL... argv) {
    final HtmlCleaner cleaner = new HtmlCleaner();
    TagNode lNode = null;
    try {
        lNode = cleaner.clean( argv[0].openConnection().getInputStream() );
        Log.d("LoadMain", argv[0].toString());
    } catch (IOException e) {
        Log.d("LoadMain", e.getMessage());
    }

    final String lTitle = "//div[@id=\"topStory\"]";
//  final String lBlurp = "//div[@id=\"topStory\"]//p";

    try {
        Object[] x = lNode.evaluateXPath(lTitle);
//      Object[] y = lNode.evaluateXPath(lBlurp);
        Log.d("LoadMain", "Title Nodes: " + x.length  );
//      Log.d("LoadMain", "Title Nodes: " + y.length);
//      this.mBlurbs.add(new BlurbView (this.mContext, x.getText().toString(), y.getText().toString() ));

    } catch (XPatherException e) {
        Log.d("LoadMain", e.getMessage());
    }

    return null;
}

任何帮助是极大的赞赏。谢谢你。

更新:我已将问题缩小到与 http 请求有关。如果我将 html 源作为资产加载,我会很清楚地得到我想要的东西,问题在于接收 http 请求。换句话说,使用lNode = cleaner.clean( getAssets().open("reuters.html") );效果很好。

4

1 回答 1

0

问题是 http 请求被重定向到移动网站。这是通过User-Agent像这样更改属性来解决的。

private static final String USER_AGENT = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:23.0) Gecko/20100101 Firefox/23.0";

HttpURLConnection lConn = (HttpURLConnection) argv[0].openConnection();
lConn.setRequestProperty("User-Agent", USER_AGENT);
lConn.connect();
lNode = cleaner.clean( lConn.getInputStream() );
于 2013-08-13T02:24:32.657 回答