Android:如何在网站包含时下载RSS:link rel =“alternate”type =“application / rss + xml”

时间:2012-05-03 02:18:31

标签: android html rss

我正在制作与RSS相关的应用程序 我希望能够只下载包含以下内容的网站URL下载RSS(xml):

link rel =“alternate”type =“application / rss + xml”

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

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

我假设我将此网站作为RSS应用程序打开,它会将我重定向到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的情况下,当我输入'http://www.engadget.com'时如何下载RSS?

2 个答案:

答案 0 :(得分:2)

要完成此任务,您需要:

  1. 检测URL是否指向HTML文件。请参阅以下代码中的isHtml方法。
  2. 如果URL指向HTML文件,请从中提取RSS URL。请参阅以下代码中的extractRssUrl方法。
  3. 以下代码是您在问题中粘贴的代码的修改版本。对于I / O,我使用Apache Commons IO作为有用的IOUtilsFileUtils类。 IOUtils.toString用于将输入流转换为字符串,如文章“In Java, how do I read/convert an InputStream to a String?

    中所建议的那样

    extractRssUrl使用正则表达式来解析HTML,即使它非常不受欢迎。 (请参阅“RegEx match open tags except XHTML self-contained tags”中的咆哮。)考虑到这一点,让extractRssUrl成为一个起点。 extractRssUrl中的正则表达式是基本的,并未涵盖所有情况。

    请注意,对isRss(str)的调用已被注释掉。如果您想进行RSS检测,请参阅“How to detect if a page is an RSS or ATOM feed。”

    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");
    

答案 1 :(得分:1)

我想显而易见的答案是,您首先获取您拥有的URL(http://www.engadget.com),然后查看HTML以查找具有正确类型的<link>标记,并且然后获取其href属性。以下是一些(Java)代码:

URL url = new URL("http://www.engadget.com");
InputStream is = url.openStream();
int ptr = 0;
StringBuffer buffer = new StringBuffer();
while ((ptr = is.read()) != -1) {
  buffer.append((char)ptr);
}
String html = buffer.toString();
Pattern rsspatt = Pattern.compile("<link[^>]*rss[^>]*>");
Matcher m = rsspatt.matcher(html);
String link = "";
if (m.find()) {
  String rsslink = m.group();
  Pattern xmllinkpatt = Pattern.compile("href=\"([^\"]+)\"");
  Matcher m2 = xmllinkpatt.matcher(rsslink);
  m2.find();
  link = m2.group(1);
}

在此结束时,变量link将为空或包含您想要的链接,您可以将其输入到downloadXml函数中。

通常我不建议通过正则表达式解析HTML,但我认为这是针对手机应用程序而你想保持简单并尽可能只使用核心。当然,如果你想得到想象,你可以使用Jsoup来检查链接标签和正确属性的存在,并提取你想要的链接。