【问题标题】:Android, Proper HTMLCleaner UsageAndroid,正确使用 HTMLCleaner
【发布时间】:2013-04-13 08:56:51
【问题描述】:

我知道我们基本上应该在这里尝试做我们自己的东西,这不是提出请求的地方,但我真的很讨厌不得不从 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 顺便说一句。然而,我确实注意到,对于每篇文章内容,某些tag hierarchy 有某种重复,它似乎是这样的:左用于图像和文章链接右用于文章标题和预览内容

所以,如果有人愿意帮助我弄清楚如何以某种方式获取内容,我将不胜感激。

顺便说一句,这个项目是为了教育目的,作为 2013 年 NASA 国际太空应用挑战赛的一部分,更多信息 here

作为一个额外问题,同一链接包含当前、未来和过去探险的信息,包括当前成员,对于探险的每个成员,都有一个指向他们的简历页面的链接。

这些标签似乎并不重复,但名称似乎是预设且不变的,您有“tab1”、“tab2”和“tab3”,等等。

我想从中获得的是:

  • 远征号和日期。
  • 探险队成员
  • 每个会员个人简历的链接。

再次感谢您的支持,如果有的话,我真的很感激。

【问题讨论】:

    标签: android html-parsing htmlcleaner


    【解决方案1】:

    所以显然我需要做的就是弄清楚如何使用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'] 表示我正在寻找类名为 landing-slide 不管 的任何 div('//'声明)它们在文档中可能位于的位置。从那里开始,我只是进一步深入项目的层次结构,最终获得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;
        }
    

    万一有人和我一样迷路了,我希望这可以为你指明道路。

    【讨论】:

      猜你喜欢
      • 2011-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 1970-01-01
      相关资源
      最近更新 更多