Android,正确的HTMLCleaner用法

时间:2013-04-19 21:09:25

标签: android html-parsing htmlcleaner

我知道我们基本上应该尝试在这里做自己的事情,这不是一个提出请求的地方,但我真的很讨厌从Html中读取内容,我真的不明白它的方法。

所以,我将获得150分的赏金(不是我便宜,我不能做更多:()如果我能得到一些好的帮助,或至少指出正确的方向与一些示例代码。

我想要完成什么?

  • 我正在尝试从以下Nasa page获取最新消息。
  • 我打算在ListView上显示这条新闻,当然,ListView开头显示的内容非常少,只有通过上面页面提供的数据,这里是一个快速的mock-up

就是这样,当用户点击一个链接时,他们将被带到一个显示完整article的不同片段,稍后我会弄清楚如何完成此操作。

所以,我尝试使用HtmlCleaner,其中包含以下内容:

private class CleanUrlTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        try {
            //try cleaning the nasa page. 
            mNode = mCleaner.clean(mUrl);
        } catch (Exception e) {
            Constants.logMessage("Error cleaning file" + e.toString());
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {         
        try {
            //For now I am just writing to an xml file to sort of read through
            //God is HTML code ugly. 
            new PrettyXmlSerializer(mProps).writeToFile(
                    mNode, FILE_NAME, "utf-8"
                );
        } catch (Exception e) {
            Constants.logMessage("Error writing to file: " + e.toString());
        }
    }       
}

但是从那里开始,我几乎迷失了。这是XML output btw。我注意到每个文章内容的某些tag hierarchy都有某种重复,它似乎是这样的:左边是图像和文章链接右边去文章标题和预览内容

Class Name Hierarchy

所以,如果有人想帮助我弄清楚如何以某种方式获取内容,我会非常感激。

作为旁注,该项目是出于教育目的,作为2013年NASA国际空间应用挑战的一部分,更多信息here

作为奖励问题,同一链接包含当前,未来和过去探险的信息,包括当前成员,并且对于探险的每个成员,都有一个指向其生物页面的链接。

这些标签似乎不是重复的,但名称似乎是预设和常量,你有“tab1”,“tab2”和“tab3”,依此类推。

我想从中得到的是:

  • 远征号码和日期。
  • Expedition Cew成员
  • 每个会员的生物链接。

再次感谢您的支持,我真的很感激。

1 个答案:

答案 0 :(得分:2)

所以显然我需要做的就是弄清楚如何使用XPATH来从XML输出中获取数据。

所以基本上,使用XPATH的想法是你可以获得任何带有XML的节点,在我的例子中,正如你在上图中看到的那样,我想获得非常具体的信息。

这是文章链接的XPATH:

public static final String XPATH_ARTICLE_LINKS = 
"//div[@class='landing-slide']/div[@class='landing-slide-inner']/div[@class='fpss-img_holder_div_landing']/div[@id='fpss-img-div_466']/a/@href";

其中//div[@class='landing-slide']表示我正在寻找任何 div ,其类名为 landing-slide ,无论('/ /'声明)它们可能位于文档中的位置。从那以后,我进一步深入到项目的层次结构中,最终获得href属性的值(属性通过'@'字符指向)。

现在我们有XPATH,我们只需要将此值传递给HTML清理器。我通过AsyncTask这样做,请记住,这不是最终的代码,但它确实得到了我想要的信息。

首先,使用XPATH:

private class News {
    static final String XPATH_ARTICLE_LINKS = 
            "//div[@class='landing-slide']/div[@class='landing-slide-inner']/div[@class='fpss-img_holder_div_landing']/div[@id='fpss-img-div_466']/a/@href";
    static final String XPATH_ARTICLE_IMAGES = 
            "//div[@class='landing-slide']/div[@class='landing-slide-inner']/div[@class='fpss-img_holder_div_landing']/div[@id='fpss-img-div_466']/a/img/@src";
    static final String XPATH_ARTICLE_HEADERS = 
            "//div[@class='landing-slide']/div[@class='landing-slide-inner']/div[@class='landing-fpss-introtext']/div[@class='landing-slidetext']/h1/a";
    static final String XPATH_ARTICLE_DESCRIPTIONS = 
            "//div[@class='landing-slide']/div[@class='landing-slide-inner']/div[@class='landing-fpss-introtext']/div[@class='landing-slidetext']/p";                       
}

现在为AsyncTask:

private class CleanUrlTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        try {
            //try cleaning the nasa page. (Root Node) 
            mNode = mCleaner.clean(mUrl);

            //Get all of the article links
            Object[] mArticles = mNode.evaluateXPath(News.XPATH_ARTICLE_LINKS);
            //Get all of the image links
            Object[] mImages = mNode.evaluateXPath(News.XPATH_ARTICLE_IMAGES);
            //Get all of the Article Titles
            Object[] mTitles = mNode.evaluateXPath(News.XPATH_ARTICLE_HEADERS);
            //Get all of the Article Descriptions
            Object[] mDescriptions = mNode.evaluateXPath(News.XPATH_ARTICLE_DESCRIPTIONS);

            Constants.logMessage("Found : " + mArticles.length + " articles");
            //Value containers
            String link, image, title, description;

            for (int i = 0; i < mArticles.length; i++) {
                //The Nasa Page returns link that are often not fully qualified URL, so I need to append the prefix if needed. 
                link = mArticles[i].toString().startsWith(FULL_HTML_PREFIX)? mArticles[i].toString() : NASA_PREFIX + mArticles[i].toString();
                image = mImages[i].toString().startsWith(FULL_HTML_PREFIX)? mImages[i].toString() : NASA_PREFIX + mImages[i].toString();
                //On the previous two items we were getting the attribute value
                //Here, we actually need the text inside the actual element, and so we want to cast the object to a TagNode
                //The TagNode allows to extract the Text for the supplied element. 
                title = ((TagNode)mTitles[i]).getText().toString();
                description = ((TagNode)mDescriptions[i]).getText().toString();
                //Only log the values for now. 
                Constants.logMessage("Link to article is " + link);
                Constants.logMessage("Image from article is " + image);
                Constants.logMessage("Title of article is " + title);
                Constants.logMessage("Description of article is " + description);

            }
        } catch (Exception e) {
            Constants.logMessage("Error cleaning file" + e.toString());
        }
        return null;
    }

如果有人像我一样迷失,我希望这可以为你的方式带来一些启示。