【问题标题】:How to detect if a page is an RSS or ATOM feed如何检测页面是 RSS 还是 ATOM 提要
【发布时间】:2011-01-27 10:20:26
【问题描述】:

我目前正在用 PHP 构建一个新的在线提要阅读器。我正在开发的功能之一是提要自动发现。如果用户输入网站 URL,脚本将检测到它不是提要并通过解析 HTML 以找到正确的 <link> 标记来查找真正的提要 URL。

问题是,我目前检测 URL 是供稿还是网站的方式仅在部分时间有效,而且我知道这不是最佳解决方案。现在我正在接受 CURL 响应并通过simplexml_load_string 运行它,如果它无法解析它,我将它视为一个网站。这是代码。

$xml = @simplexml_load_string( $site_found['content'] );

if( !$xml ) // this is a website, not a feed
{
    // handle website
}
else
{
    // parse feed
}

显然,这并不理想。此外,当它遇到一个它可以解析的 HTML 网站时,它认为它是一个提要。

关于在 PHP 中检测提要或非提要之间差异的好方法有什么建议吗?

【问题讨论】:

    标签: php rss feedparser atom-feed


    【解决方案1】:

    使用 Content-Type HTTP 响应标头分派到正确的处理程序。

    【讨论】:

    • 我认为他的问题更深层次,他需要使用许多 RSS 源,其中许多甚至不能以他们选择的格式提供有效的标记 - 更不用说发送正确的内容类型标头了。
    【解决方案2】:

    我认为您最好的选择是获取 Content-Type 标头,因为我认为这是 Firefox(或任何其他浏览器)的方式。此外,如果你仔细想想,Content-Type 确实是服务器告诉用户代理如何处理响应内容的方式。几乎所有体面的 HTTP 服务器都会发送正确的 Content-Type 标头。

    但是,如果第一个“失败”(此标准取决于您),您可以尝试将内容中的 rss/atom 识别为第二个选择。

    另一个好处是您只需要请求标头而不是整个文档,从而节省带宽、时间等。您可以使用 curl 执行此操作,如下所示:

    <?php
     $ch = curl_init("http://sample.com/feed");
     curl_setopt($ch, CURLOPT_NOBODY, true); // this set the HTTP Request Method to HEAD instead GET(default) and the server only sends HTTP Header(no content).
     curl_exec($ch);
     $conType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    
     if (is_rss($conType)){ // You need to implement is_rss($conType) function
        // TODO
     }elseif(is_html($conType)) { // You need to implement is_html($conType) function
        // Search a rss in html
     }else{
        // Error : Page has no rss/atom feed
     }
    ?>
    

    【讨论】:

      【解决方案3】:

      我会嗅探这些格式所具有的各种唯一标识符:

      原子:Source

      <?xml version="1.0" encoding="utf-8"?>
      <feed xmlns="http://www.w3.org/2005/Atom">
      

      RSS 0.90:Source

      <rdf:RDF
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns="http://my.netscape.com/rdf/simple/0.9/">
      

      网景 RSS 0.91

      <rss version="0.91">
      

      等等。等(完整概述请参见第二个源链接)。

      据我所知,通过分别查找&lt;feed&gt;&lt;rss&gt; 标签来分离Atom 和RSS 应该很容易。另外,您不会在有效的 HTML 文档中找到它们。

      您可以通过首先查找 &lt;html&gt;&lt;body&gt; 元素来进行初步检查以区分 HTML 和提要。为了避免无效输入的问题,这可能是最终证明使用正则表达式(通过解析器)的情况for once :)

      如果它与 HTML 测试不匹配,请对其运行 Atom / RSS 测​​试。如果它未被识别为提要,或者 XML 解析器因输入无效而阻塞,请再次回退到 HTML。

      在野外看起来是什么样子 - 提要提供者是否总是遵守这些规则 - 是一个不同的问题,但您应该已经能够通过这种方式识别很多。

      【讨论】:

      • 是的,他们应该有那些标签标识符。但是那里有很多格式不正确的提要和不同的版本,我不能依赖它。寻找 或 标签很有趣。我会测试一下。
      • @Pepper 是的,也许编译标签列表来嗅探? htmlbody 用于 HTML,rdfitem (IIRC) 用于 RSS,feed 用于 Atom....
      【解决方案4】:

      为什么不尝试使用专门为解析 RSS/ATOM Feed 而构建的组件来解析您的数据,例如 Zend_Feed_Reader

      这样,如果解析成功,您将非常确定您使用的 URL 确实是有效的 RSS/ATOM 提要。


      而且我应该补充一点,您也可以使用这样的组件来解析提要以提取它们的信息:无需重新发明轮子,解析 XML“手动”,并处理特殊情况自己。

      【讨论】:

      • 使用 simplexml_load_string 并手动解析对我有用,它正在检测网站和提要之间的差异,这就是问题所在。不过谢谢;)
      • 如果提要是格式错误的 XML 怎么办?您是否能够解析标签和附件等提要的所有扩展?也许您不关心这些事情,但我的经验是,提要并不像您期望的那样标准化,并且使用现有的库可以防止您重新发明轮子。
      • 我试试 Zend_Feed_Reader。我在项目早期尝试了 SimplePie,我自己解析它的成功率更高。你说得对,提要没有标准化,那里一团糟。
      猜你喜欢
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 2011-04-26
      相关资源
      最近更新 更多