`
61party
  • 浏览: 1047781 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Blog外挂之:妙用del.icio.us实现“站内相关文章”

阅读更多

Blog外挂之:妙用del.icio.us实现站内相关文章

By 刘未鹏(pongba)

C++的罗浮宫(http://blog.csdn.net/pongba)

先说明一下,其实这个方法是跟Blog无关的,只要支持插入javascript代码的blog都可以使用。

废话少说,翠花,上图片先:

图片截取自:月光博客

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414pt; HEIGHT: 252.75pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg" o:title="ra_demo"></imagedata></shape>

图片截取自:ThinkingParallel

<shape id="_x0000_i1026" style="WIDTH: 382.5pt; HEIGHT: 276.75pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image002.jpg" o:title="ra_demo1"></imagedata></shape>

<shape id="_x0000_i1027" style="WIDTH: 239.25pt; HEIGHT: 246pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.jpg" o:title="ra_demo2"></imagedata></shape>

是不是很眼馋这些功能?站内相关文章文章排行文章评价文章相关tags,以及全局tags

所有这些功能的最大好处不是漂亮,而是实用。其实用之处在于能够增加blog的粘着度。一般来说如果是一个简陋的blog,如果别人从一个文章链接跳到你的blog上看了一篇文章,那么很可能看完就走了,但如果能在文章的正下方跟着显示相关文章的话,粘着度就会得到大大的提高。相关文章其实就是简单的关联挖掘,而后者是所有网上营销类网站的最大法宝之一(有人见过不用“读(买)过的人也读(买)过”的网上书店吗?)。

可惜的是,除了很少一些独立blog具有这个功能之外,国内外的博客系统目前基本都没有这个功能,似乎就连最好的免费blog系统wordpress也还没有增加这个功能。

CSDN blog 06年的时候还有过一阵子的“相关文章”栏的,如图:

<shape id="_x0000_i1028" style="WIDTH: 413.25pt; HEIGHT: 137.25pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image004.jpg" o:title="ra_demo4"></imagedata></shape>

可后来广告栏上去了,相关文章栏消失了。不过CSDN blog的广告栏还算是做得蛮有心的,首先不像live space的广告栏那样不尊重用户,弄一个花花绿绿还闪啊闪的Flash大摇大摆的放在blog主页的正上方,跟人家把脑白金广告贴到你家门匾上一样,丑就不说了,太影响阅读情绪。Donews曾经仿效了一次,结果被群起而讨伐之,只好又灰溜溜改回去。其实BSP运营不容易大家也都有数,像新浪blog这样的毕竟在少数。所以放点广告大家也能理解,但所谓盗亦有道,放广告也要讲技巧。我最欣赏的就是Gmail的广告投放,根据email的内容进行关联挖掘,投放最可能对你有用的广告,这甚至已经不能算是一种广告,简直是双赢了。而且文字广告不那么扎眼,较之图片广告看起来要舒服很多;这也是我抛弃hotmailyahoo mail的原因。CSDN blog的广告栏总算比较人道,不乱投垃圾,不乱放图片,也用上了关联挖掘;但之所以提这个广告栏,最重要的一点还是它很有用,待会你就会知道。

再来说06年还在的那个“相关文章”栏,我不大清楚CSDN为何把这个栏目撤掉,这是个能增加blog粘着度的功能。但最重要的一点是,原先CSDN blog上的“相关文章”栏的“相关”是指全站的相关文章。而不是你自己blog上的相关文章。这就让人很不爽,并不是说全站相关不好,只是应该再增加一个“本站相关文章”才是。

那是不是就没办法了?老大们都是程序员吧,程序员会干嘛?不,不是指泡MM,是编码。所以现在不管怎样,我们还是需要自己实现一个“站内相关文章”功能出来。

我对web开发基本可以说是七窍通了六窍,以前没写过一行Javascript代码,没写过一个网页。大一的时候玩过一阵子flash,早已全还掉了。但web盲归web盲,要实现这个功能,大致思路还是可以想出来的。

CSDN blog不知道有没有开放获取文章tag以及根据tag获取文章的JSON接口,就算开放了也要精确到个人blog才行,就算精确到了个人blog也还有修改tag不方便等问题。所以不管怎样,依赖CSDN blog开放接口是不大可能了。

上次写到如何del.icio.usblog加上tags,那个比较简单,只要用del.icio.us现成的tagrolls功能即可。这次仍然还是用del.icio.us的功能,不过这次del.icio.us没有提供现成的功能,要自己根据它开放的JSON接口来实现。

实现耗了一些时间,没办法,谁叫俺不是web开发出身呢?只好乖乖拉出犀牛书,架上google,“边搜索边编程”:)

“本站相关文章”1.0

忙活了几个小时,总算搞定了一个1.0版,顺便也了解了一下JSONdel.icio.us的开发接口,还学了不少javascript。总算也有点了解为什么有那么多人鼓吹动态语言了——上手很快,很直观灵活。另外感觉反射特性(reflection)web开发实在是很重要。

1.0版实现的效果如下

<shape id="_x0000_i1029" style="WIDTH: 372pt; HEIGHT: 439.5pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image005.jpg" o:title="ra1"></imagedata></shape>

为什么这个“本站相关文章”会出现在“特别推荐”的上面,等会解释。先来说说这个实现的问题。

我假设你已经像上篇里面说的,将你blog上的所有文章链接导入到一个专门的del.icio.us帐号上了,比如我的。这样一来这个del.icio.us帐号便存储了你的blog上所有文章及其所属tags的信息,这些信息已经足够用了,关键是怎么提取出来。

在最初实现这个功能的时候,本想用URL feed来获取当前url(document.URL)的相关信息,然后从其中抽取出相关的tags,然后再使用posts feed来获取与这些tag相关的posts,便大功告成。

谁知道算盘打得响当当的,实现起来就处处问题了,首先的问题就是URL feed只能获取一个urldel.icio.us全站上的tags,而且还是top tags,如果你的文章被别人save得不多,那么就算你给它加了十个tag,最后返回的tag集合也有可能是空的,因为它返回的是top tags。我不知道del.icio.us是怎么计算top tags的,可能有一个最少被save数目加一个百分比,但无论如何,这个办法是没法获取到你给你的一篇文章加上的所有tags的。没法获取其所有tags,便没法很好地获取与其相关的文章了。

硬着头皮试了一下,能获取到的tags极少,而且还可能是人家标的,不是你自己标的。只好放弃,另辟他径。

一拍脑袋方才想起del.icio.usposts feed是能够获取所有posts的详细信息的,获取到的是一个数组,其中每个元素都是一个posts的相关信息集合,后者包括它的链接标题注释tags。这下问题不就结了?只要遍历一下这个数组,把当前文章url往里面一个个的比,直到找到代表当前文章的那个JSON对象,提取其中的tags。然后用这些tags再往里面作一次相关搜索,搜索出相关的JSON对象,提取出他们的标题和链接,done

目前的版本(2.0+)采用的也正是这个办法。

改进

现在的问题是“相关搜索”如何做。我们知道,一篇文章可能有多个tags,那么怎么判定另一篇文章是和它相关的呢?一个最简单的办法是取该文章的第一个tag(这依赖于你在导入文章链接的时候将其第一个tag设为tag),然后找出所有包含该tag的其它文章。这个办法是可行的,也是上面展示的1.0版采用的办法。

但这个办法有一个大问题,就是它依赖于你对任意一篇文章所设的第一个tag必须是最能反映这篇文章内容的tag,不够自动化,我们平常给文章设tags的时候一般都是松散的,哪考虑那么多,结果为此就要去del.icio.us上调整tag顺序,很麻烦。此外的一个问题是,和该文章亲缘关系较远的文章就显示不出来了。比如一篇boost源码剖析,它既属于boost又属于GP,还属于C++。那如果选”boost”为它的tag,那么就只能显示含”boost” tag的文章了,如果这些文章较少,只有聊聊几篇,而这时你想退而求其次显示一些GP的怎么办呢?

另一个问题是1.0版的选择相关文章的算法是从头到尾遍历的,而你选出来的相关文章数目又必须设一个上限,否则遇到大类的时候就会拉出长长一串来,不好看,噪音也太大。这就导致一些比较久远的文章可能总是不会被选到,你可能不希望看到这种情况,因为文章年代久远并不一定代表它就不好看了:-) 这个问题易于解决,只要引入一个随机选择过程即可——先找出所有相关的文章,然后随机选取maxSize个(maxSize是你的“本站相关文章”框的大小限制)。

亲缘关系的判定则要麻烦一些。如果不依赖于用户指定第一个tagtag的话,又该如何判定一个tag跟当前文章的主题亲缘关系有多紧密呢?

理想的设想应该是这样的,对于一篇特定的文章,我们想首先找出最能反映它的主题的tag,然后找出所有包含该tag的所有其它文章,显示出来。如果这时候还没达到maxSize个,我们就选一个tag,接着显示,以此类推

那么,如何判定一个tag与特定文章的“相关性”便成了最大的问题。以上的问题就是2.0要解决的问题了。

“本站相关文章”2.0

2.0判断tag相关性依赖于一个简单的观察:即在与一个文章有关的多个tag中,那些总体被使用最少的tag一般就是最specific的,次少的则是次specific的,以此类推。这是因为我们平常对一篇文章分类的时候一般是树状的,越往树顶去的tag越大,同时也越。而越往枝叶部分去的tag越小,也越specific。所以,如果将一篇文章的所有tags按从小到大排序,那么遍历过去就基本相当于在tag-tree上从叶节点往根节点移动的过程。

基于这个想法修改了一些代码。效果不错,如下

这是一篇《读古龙的岁月》系列文章的相关文章列表:

<shape id="_x0000_i1030" style="WIDTH: 344.25pt; HEIGHT: 306pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image006.jpg" o:title="ra2"></imagedata></shape>

注意,显示在最上面的是关联最紧密的tag和文章,然后亲缘关系逐步疏远。直到满12篇(我设的上限(maxSize)是12)为止。此外,我把通过同一个tag找到的相关文章分了组,并在前面加上了该组的tag,这样使得结构更分明,信噪比也更大一些

一个要注意的小问题是要避免不同组之间显示的文章的重复。

“本站相关文章”2.1

“本站相关文章”2.1主要添加了一个小功能,就是显示“本文相关tags”,如图:

此外2.1的另一个小修正就是当别人从一个comments链接打开一篇文章的时候能够正确处理。因为这时document.URL并不是你收藏的那个URL,而是后面加上了”#comments”,于是你就得把这个尾巴去掉才行。

为什么链接放在“特别推荐”广告栏的上方

简单的答案是“找不到其它合适的地方好放”。如果你查看一下你的CSDN blog的页面源代码,你会发现有”id”属性的div不是很多。其实最理想的地方是紧跟在你发表的文章的结尾另起一行,但因为发表文章的div块没有id,而通过编号来定位的方法又过于fragile,所以只好退而求其次。

广告栏的div是有id的,名为”csdn_zhaig_ad_yahoo”,之所以有id是因为CSDN本身也要用javascript往这个div里面写内容,所以不妨“复用”一下这个div,把我们的内容也写到里面。幸运的是,这个div的位置刚刚好在文章的正下方。呵呵,希望CSDN不会修改广告栏div的位置,否则只好往comments那个div里面写了:-)

其实不写在这个div里面也可以,你可以写到侧边栏上,不过这在用户行为学上不是最佳的,别人看你文章的时候可能只会一路往下扫着看,一般不会去注意侧边栏的。

CSDN Blogjavascript代码

在写javascript代码的时候也顺便看了一下CSDN Blog本身是如何填充那个广告div的,结果吓了一跳:

document.getElementById("csdn_zhaig_ad_yahoo").innerHTML=outhtml;

幸好main那个divrightmenu那个div加载得早,而我们的javascript代码放在rightmenu里面。这要是反过来,我们辛辛苦苦写的内容就得生生给覆盖掉了。

其实直接修改innerHTML的这种方式并不是最佳的写页面方式(也不是最厚道的:P。再看看这个:

document.write('<script language = "JavaScript1.1" src='+str+"><\/script>");

汗,好大一个document.write。这是最不推荐使用的写方式了,而且还是直接写HTML代码

俺虽然土,只接触web编程一下午,犀牛书基本从索引翻起,那也是知道应该用:

var script = document.createElement('script');

script.setAttribute('type', 'text/javascript');

script.setAttribute('src', calledURL);

ct. appendChild (script);

这种方式,不硬编码,不出现raw string,杀人不见血,实在是居家旅行,必备之良药

应用到非CSDN Blog

其实这个方法是跟Blog无关的,只要支持插入javascript代码的blog都可以使用,当然,另一个前提是你得找到能够插入相关文章链接的div才行,比如CSDN Blog就比较厚道,刚好提供了一个广告div:-) 不过你可别像上面给出的代码那样直接写innerHTMLdon’t be evil:-) 把人家广告覆盖掉了也不够厚道是不是?人家对你厚道你总得投桃报李吧:P

总结

我们借助del.icio.us的社会化书签功能和开放JSON接口实现了一个非常酷非常有用的“本站相关文章”系统,这个系统可以移植到任何支持插入javascript代码的blog,并且非常灵活,只依赖于del.icio.us。其唯一的弱点是当前del.icio.usposts feed目前只支持最多获取100post。如果哪位老大blog上的文章实在太多的话,有两个权宜之计,一是“精选”一下你的好文章收藏到del.icio.us上,如果“精选”之后精品实在还是太多的话,呵呵,那就只好再申请一个font-size: 12pt; font-family

分享到:
评论

相关推荐

    鲜果阅读器

    * 与DEL.ICIO.US网络收藏夹完美的融合; * 可灵活的和Bloglines.com集成; * 支持频道列表的导出备份; * 用内建浏览器时,自动识别网页上的RSS Feed; * 本地文章快速搜索; * 信息脱机浏览;

    鲜果阅读器1.0版发布 (免费)

    * 与DEL.ICIO.US网络收藏夹完美的融合; * 可灵活的和Bloglines.com集成; * 支持频道列表的导出备份; * 用内建浏览器时,自动识别网页上的RSS Feed; * 本地文章快速搜索; * 信息脱机浏览;

    MonkeyChow:请注意,该项目现在为https://github.com/shokk/MonkeyCh-开源

    带有社交书签(del.icio.us,Blogger,Newsvine,Technorati,mailto)的Feed Aggregator Reader(从FeedOnFeeds分支),文章加注星标,Feed标记,OPML,文章搜索,重新博客和重新供稿,老化和编辑供稿属性。...

    PHP博客源码WikyBlogv1.7.3RC1多国语言版

    WikyBlog支持:多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WikyBlog v1.7.3 RC2 多国语言版.rar

    WikyBlog支持: ...多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WikyBlog v1.7.2 多国语言版.rar

    WikyBlog支持: ...多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WordPress网络书签插件Share this

    在进行中文化的过程中,主要是把去掉了国外不常用的网络书签,加上了国内主流的网络书签、社区、微博客分享等,分别包括:Del.icio.us(美味书签)、我挖网(DigBuzz)、QQ书签、收客网(Shouker)、百度搜藏、趣摘网...

    WikyBlog.zip_WEB开发_PHP-PERL_

    WikyBlog支持:多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WikyBlog v1.7.2 多国语言版

    WikyBlog支持: ...多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WikyBlog博客程序 v1.5.3多国语言版

    WikyBlog支持:多用户的 BLOG,每个用户的BLOG都可用简单的URL访问,很像 del.icio.us 的用户URL访问方式,BLOG 的书写语法与 Mediawiki 一致,支持 Tags 文章分类,便于查找相关文章,支持 AJAX。

    WikyBlog 1.7.3 rc2

    WikyBlog是一款基于...WikyBlog支持:多用户的BLOG,每个用户的BLOG都可用简单的URL访问,很像del.icio.us的用户URL访问方式,BLOG的书写语法与Mediawiki一致,支持Tags文章分类,便于查找相关文章,支持AJAX。

    WikyBlog v1.7.3 RC1多国语言版

    多用户的BLOG,每个用户的BLOG都可用简单的URL访问,很像del.icio.us的用户URL访问方式,BLOG的书写语法与Mediawiki一致,支持Tags文章分类,便于查找相关文章,支持AJAX。 使用前请按要求进行安装。

    WikyBlog博客程序 v1.4a多国语言版

    安装过程是纯英文的,很简单。...WikyBlog支持:多用户的BLOG,每个用户的BLOG都可用简单的URL访问,很像del.icio.us的用户URL访问方式,BLOG的书写语法与Mediawiki一致,支持Tags文章分类,便于查找相关文章,支持AJAX

    一种自动社交标签的混合方法

    通过在Del.icio.us数据库中的50,000培训和10,000测试网页上进行的实验,结果表明我们的混合方法优于四个基准。 此外,与两种主题模型Corr-LDA和混合成员LDA相比,我们的方法分别使NDCG10改善了14.2%和25.6%。

Global site tag (gtag.js) - Google Analytics