打造基于Google API的文章关联服务

请输入图片描述

这些日子一直有人在问我要Magike的“相关文章”插件,大家也不理解为什么像“相关文章”用户体验这么好的东西,为什么我不放到程序中。实际上我要说的是,像blog这种个人站点如果消耗自己的资源来做相关文章实际上是得不偿失的。首先是消耗服务器资源,相关文章的匹配查询是很消耗资源的,无论你做什么样的优化都是如此。其次是准确度也有问题,如果你想让查询更加轻便那么准确度就会下降。

那么有没有比较好的解决方案呢?答案是肯定的。我们可以通过google提供的API来打造完全适合本站的文章关联服务,如果你熟悉google的API你会发现它提供了一个叫做Google Feed Ajax的API,这个API可以跨域地实现feed的调用。没错,它是跨域的,但是通常我们都说AJAX是无法跨域的,难道google有什么独门秘笈或者后门吗,其实google使用的并不是ajax技术。如果你用过jQuery,那么你肯定知道jquery里面有一个getScript的API,它在1.2.0的版本后增加了一个新特性"across domain",就是跨域。在1.2.0以前这个函数是无法实现跨域的,因为它使用的是ajax方法把js从本域中取出然后执行,而1.2.0以后它是通过在header里面把script节点动态增加进去实现跨域调用的,因为我们都知道,script标签是可以调用其它站点的js脚本的,而一旦你动态的修改了header里面的节点,浏览器就会自动去下载并执行这些资源(这是浏览器的特性决定的),这种跨域的实现颇有些hack的味道,但是的确非常可行,因为已知的浏览器都支持这种方式。

通过上面的解释,你大概可以知道google的跨域ajax实现方法,它把执行结果封装为一个js对象然后把这个url动态加载到我们浏览器的header里,我们浏览器会自己去下载这个对象,这样一次完整的异步请求就完成了。不过就算你不知道上面的东西也不要紧,因为google已经帮我们封装好了所有的应用,你所要做的就是去使用它们。

上面介绍的Google Ajax Feed API可以帮我们解决跨域调用的问题,算是为我们达到目的造了一座桥,但是我们还需要找一个地方来获取我们需要的内容(也就是相关文章)。我把目光锁定到了google blog search,原因很简单第一它够快,第二它的查询结果可以以rss feed的方式输出,这样我们就可以用Google Ajax Feed API取出查询的结果,然后将它动态地显示出来。好了,暂时收敛一下内心小小的激动,让我们来关注一下google blog search的查询字符串组成格式,这样我们就可以动态构造查询了。通过观察我们发现它的url构成是如下形式

http://blogsearch.google.cn/blogsearch_feeds?hl=zh-CN&q=xxx
+blogurl:www.joyqi.com&ie=utf-8&num=10&output=rss

其中xxx代表我们的查询字符串,而后面的www.joyqi.com则表示我们需要查询的网址。因此接下来我们要做的就是把xxx替换成我们需要查询的关键字,剩下的匹配工作就可以交给google了。那么如何获取我们当前文章的关键字呢,这就需要靠你的blog系统输出了,一般可以用tags代替。如果你使用的是Magike系统,那么你可以通过调用{$static_var.keywords}来获取当前页面的关键字。所以最后我们得到的代码就是

google.load("feeds", "1");
    function initialize() {
      keyword = "{$static_var.keywords}";
      keyword = keyword.replace(",","+OR+");
      keyword = encodeURI(keyword);
      var feed = new google.feeds.Feed(
      "http://blogsearch.google.cn/blogsearch_feeds?hl=zh-CN&q="
       + keyword + "+blogurl:www.joyqi.com&ie=utf-8&num=10&output=rss");
      feed.load(function(result) {
        if (!result.error) {
          var container = document.getElementById("related-posts");
          container.removeChild(document.getElementById("loading"));
          num = 0;
          
          for (var i = 0; i < result.feed.entries.length; i++)
          {
            var entry = result.feed.entries[i];
            if(entry.link != "{$post.permalink}")
            {
                var li = document.createElement("li");
                var a = document.createElement("a");
                a.setAttribute("href",entry.link);
                a.appendChild(document.createTextNode(entry.title));
                li.appendChild(a);
                container.appendChild(li);
                num ++;
            }
          }
          if(num == 0)
          {
                var li = document.createElement("li");
                li.appendChild(document.createTextNode("No entries..."));
                container.appendChild(li);
          }
        }
      });
    }
    google.setOnLoadCallback(initialize);

没错,是google.cn提供的feed,因为通过对比我发现google.cn对中文blog的更新速度比较快,而且匹配也更加准确。注意,以上代码仅适用于我的页面,如果你想用到自己的blog上面还需要做一些修改。但是大体的思路就是这个样子,最后你千万别忘了在这段代码之前引用一下google api的js库,也就是

<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAHJ7Azkbtr36CZ_qMQxedShT4cNR6wnZCCzwFMKUsRU_kuBOHZxREVOHaNP1UK2G4pPcWGsI7X_B2pg"></script>

其中key后面的是google提供的API KEY,你需要到它的网站申请,这个key只对申请的网站有效。

已有 15 条评论

  1. LJ LJ

    一定要有key才可以用google blog search的链接吗?
    还有.好像我的还没被google blog收录.汗

  2. magike magike

    Key是Google API用的,你如果经常换地址就很难被收录了

  3. LJ LJ

    二级目录会不会影响key?
    我注册时是www.XXX.name 用时是 /X 目录

  4. magike magike

    应该不会影响,你试试看就知道了,如果影响再重新申请就行了

  5. sluke sluke

    这个功能还是可以作为插件出现的。

  6. Gaoliu Gaoliu

    没搞过的东西,也是不感兴趣的东西。

  7. 192.168.0.110 192.168.0.110

    同喜PR升至4.

  8. dc dc

    这么巧,我最近也在看Google API
    地图那一块很有意思

  9. aw aw

    你的joyqi的留言体验太差了。。。。。

  10. magike magike

    下一步就是改善留言体验了

  11. digbuzz digbuzz

    好文,放到我挖网( digbuzz.com , 最大的中文 Digg)挖一挖会不错,还可给你带来大量流量!

  12. calvin calvin

    不错~ o(∩_∩)o... 用用看 ~~~

  13. this is very good

    good related article

  14. 用Google Ajax Feed API的Slide Show实现图片幻灯片展示 | fangyi's blog

    [...]四、不过虽然放弃这个方案, 但并非我就一无所获。google的这个api提醒我可以用读取rss(当然不再是跨域读取,因为跨域读取不会是实时的;我可以试试这里提示的jQuery的getScript函数)的方式来实现图片的展示,创建一个基于yahoo media rss的标准rss是很有利的,这样还可以开放自己网站的api,让别的站点调用自己站点rss上的图片(当然,这时可以用google的api了,[...]

  15. AK47 » links for 2008-02-29

    [...]打造基于Google API的文章关联服务 » Joyqi.com - 关注生活,关注互联网[...]

评论已关闭