我正在构建一个简单的新闻阅读器应用程序,并使用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+,这是正确的。
这是我现在的密码。它在一个扩展AsyncTask
的Android类中,所以它是在后台执行的。最后的代码实际上会得到我需要的文本数据,但我很难让它返回结果。当我记录标题节点时,节点计数为零。
我已经尝试了各种转义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") );
工作得很好。
问题是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() );