Android ︰ 如何下载 rss 订阅,当一个网站包含︰ 链接 rel ="候补"类型 ="应用程序/rss + xml"

标签: Android HTML
发布时间: 2017/3/14 0:08:43
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我正在做一个 RSS 相关应用程序。
我想要能够下载 RSS ( xml ) 给出了包含的网站 URL:

链接 rel ="候补"类型 ="应用程序/rss + xml"

例如, http://www.engaget.com源包含︰

<link rel="alternate" type="application/rss+xml" title="Engadget" href="http://www.engadget.com/rss.xml">

我假设如果我打开这个网站作为 RSS application
我一点它会重定向到http://www.engadget.com/rss.xml页。

我下载的代码 xml 如下︰

private boolean downloadXml(String url, String filename) {
        try {
            URL   urlxml = new URL(url);
            URLConnection ucon = urlxml.openConnection();
            ucon.setConnectTimeout(4000);
            ucon.setReadTimeout(4000);
            InputStream is = ucon.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is, 128);
            FileOutputStream fOut = openFileOutput(filename + ".xml", Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
            OutputStreamWriter osw = new OutputStreamWriter(fOut);
            int current = 0;
            while ((current = bis.read()) != -1) {
                osw.write((byte) current);
            }
            osw.flush();
            osw.close();

        } catch (Exception e) {
            return false;
        }
        return true;
    }

我不知道 'http://www.engadget.com/rss.xml' url,怎样才能下载 RSS 当我输入 http://www.engadget.com"?

解决方法 1:

要做到这一点,您需要︰

  1. 检测是否 URL 指向 HTML 文件。看到 isHtml 在下面代码中的方法。
  2. 如果 URL 指向 HTML 文件,从中提取 RSS URL。看到 extractRssUrl 在下面代码中的方法。

下面的代码是代码的修改后的版本粘贴在你的问题。对于 I/O,我用于Apache 共同性 IO有用 IOUtilsFileUtils 类。 IOUtils.toString 用于将输入的流转换为字符串,如文章推荐"在 Java 中,如何做我读/转换为字符串的题目:?"

extractRssUrl使用正则表达式解析 HTML ,即使它高度皱眉头。(见"正则表达式匹配开放标记除了 XHTML 自包含标签。"咆哮着)为此,让 extractRssUrl 会开始 point 。正则表达式在 extractRssUrl 是简陋,并不涵盖所有的情况。

请注意,调用 isRss(str) 被注释掉。如果你想要做 RSS 检测,请参阅"如何检测如果页是 RSS 或 ATOM 源"。

private boolean downloadXml(String url, String filename) {
    InputStream is = null;
    try {
        URL urlxml = new URL(url);
        URLConnection ucon = urlxml.openConnection();
        ucon.setConnectTimeout(4000);
        ucon.setReadTimeout(4000);
        is = ucon.getInputStream();
        String str = IOUtils.toString(is, "UTF-8");
        if (isHtml(str)) {
            String rssURL = extractRssUrl(str);
            if (rssURL != null && !url.equals(rssURL)) {
                return downloadXml(rssURL, filename + ".xml");
            }
        } else { // if (isRss(str)) {
            // For now, we'll assume that we're an RSS feed at this point
            FileUtils.write(new File(filename), str);
            return true;
        }
    } catch (Exception e) {
        // do nothing
    } finally {
        IOUtils.closeQuietly(is);
    }
    return false;
}

private boolean isHtml(String str) {
    Pattern pattern = Pattern.compile("<html", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
    Matcher matcher = pattern.matcher(str);
    return matcher.find();
}

private String extractRssUrl(String str) {
    Pattern pattern = Pattern.compile("<link(?:\\s+href=\"([^\"]*)\"|\\s+[a-z\\-]+=\"[^\"]*\")*\\s+type=\"application/rss\\+(?:xml|atom)\"(?:\\s+href=\"([^\"]*)\"|\\s+[a-z\\-]+=\"[^\"]*\")*?\\s*/?>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
    Matcher matcher = pattern.matcher(str);
    if (matcher.find()) {
        for (int i = 1; i <= matcher.groupCount(); i++) {
            if (matcher.group(i) != null) {
                return matcher.group(i);
            }
        }
    }
    return null;
}

上面的代码的工作与你 Engadget 示例︰

obj.downloadXml("http://www.engadget.com/", "rss");
官方微信
官方QQ群
31647020