级别: 初级 Uche Ogbuji (uche.ogbuji@fourthought.com), 首席顾问, Fourthought Inc.
2006 年 11 月 27 日 本文中,您将了解如何利用以 Python 和 ECMAScript 编写的 Web XML 提要和 JSON,从而通过 del.icio.us 工作,del.icio.us 是一流的 Web 2.0 站点之一。在考虑 Web 2.0 技术时,您可能会想到最新的 Ajax 技巧,但那仅仅是其中的一小部分。更根本的关注点是开放数据、简单 API 以及鼓励用户形成社会网络的功能。这些更使 Web 2.0 成为让 Web 架构师关注的重要问题。此专栏文章将深入研究实际的 Web 2.0 站点,并演示 Web 架构师如何将 Web 中的最佳内容引入他们自己的网站。
当人们列出一流的 Web 2.0 站点时,有一个站点总是位于其中,那就是 del.icio.us(请参阅 参考资料 中的链接)。尽管该站点相对来说还比较新,但它却是公认最好的社会书签站点。它允许人们向这些链接发布链接和标记。它为链接集合提供 Web 提要,包括为很多用户已发布的链接自动聚合标记,如特殊的 popular 标记等。它还提供简单和开放的 API。del.icio.us 还展示出 Web 2.0 这个术语有多么模糊。您可能希望看到一个出色的、由 Ajax 驱动的网页,其中具有充满诱惑力的 Web 对话框。在这一点上,del.icio.us 根本不是您想像的那样;它非常简单,以提供功能为主旨。最近其主页已经做了很多修饰,过去的界面一直非常朴实。
共享浏览器书签的想法并不是新想法。在 .com 时代,出现了诸如 Backflip 之类的服务,借助这些服务,人们能够在线托管并分类书签。Backflip 是免费的,但是这些站点(如 del.icio.us)的创新在于信息更自由:可以通过很多方式免费获得和使用,以多种模式共享。Open API、Web 提要(如那些在 RSS 和 Atom 上构建的提要)以及借助自动聚合进行标记都是在 Web 上实现更有吸引力的开发的基础,这一切往往和用户界面技巧(如 Ajax)集中在一起。有时这些合作的功能被 Web 那种典型的受限的界面所牵制,因此,有时只需略加点拨便能使更多人有可能涉足 Web 2.0,使 Web 2.0 对他们更有吸引力,通常,此类站点的价值与参与者的数量成正比。
有效的 Web 2.0 站点的主旨以及 Web 架构师(与 Web 设计师等角色相对)的兴趣点在于真正的开发人员和用户能够非常轻松地利用开放数据功能。从用户用于在社会站点上自定义其领域的小部件,到开发人员用于通过 Web 2.0 双亲创建后代的 mashup,有很多方式可以理解致使此类站点成功的因素,理解应该如何在自己的工作中模仿此类成功的站点。真正的 Web 2.0 专栏将拨开宣传的迷雾,将重点放在从 Web 架构师看来站点最宝贵的实际功能上。在第一篇期中,我将从此类站点的先驱之一 del.icio.us 开始。
门面
在此专栏中,我将 Web 2.0 站点的主页称为它的门面。这是因为它就像建筑的门面一样,是惟一的正面,大部分实际业务都发生在可视性较差的区域。我几乎每天使用 del.icio.us,但是,我几乎从来没有为它的门面而操心过。我使用 Firefox 插件将感兴趣的站点发布到 del.icio.us。我在 Web 提要阅读器中的 popular 标记上关注所有条目,每天使用简单的 Python 脚本自动将我的 del.icio.us 发布内容发布到我的博客上。这就是我说过的,在 Web 2.0 中很多真正的业务都发生在门面背后的含义。不过,主页是您的入口,因此,我将从这儿开始。
del.icio.us 的主页尝试提取用户标记的主要趋势。它列出了近来被很多人加为书签的 hot now 网页。还列出了编辑认为特别有趣的一些标记。其中有站点所有者的托管博客,还有最新的条目,祝贺站点在经过 3 年运营之后现在已有一百万注册用户。对于使开放数据支持一组贡献者(工具、插件、mashup 以及更多内容的开发人员),del.icio.us 的确演示了如何拥有良好的架构特性,从而带来更多用户、吸引更多的贡献者,这是一个良性循环。
家,甜蜜的家
注册用户都有一个主页,这个主页可以使用非常简单的 URL 方案访问:http://del.icio.us/<username>。一种非常明智的 URL 方案是站点持久生命力的源泉之一,它的价值远远超过门面,我将在后面对此进行讨论。您的主页包含您最近发布的链接和标记。图 1 演示了我自己的 del.icio.us 页面的一部分。
图 1. del.icio.us 用户主页
与大多数 Web 2.0 页面一样,简单、分门别类的关键词或标记 是 del.icio.us 的基本特性,该站点成了标记云(tag cloud) 概念的先锋。您可以在 图 1 的右侧看到标记云。它是标记术语的列表,一些术语字体较大或者采用了黑体,这取决于它们的使用频率。在 Web 2.0 的世界中有很多关于将标记云作为可视化隐喻是否有效的讨论,实际上,del.icio.us 后来已略微弱化了这一特性。
您还可以看到站点的一些聚合功能,站点采用这种方式突出显示了很多其他用户所链接到的一些链接。从您的用户页面中,您可以搜索您的链接以及社会网络(您指定的、对其链接感兴趣的人的列表)。尽管您还可以如上所述访问 Web 用户界面以便发布和管理条目,但是,很多用户都会利用主页以外的工具来完成此任务。
本土方法
您可能只是对门面仰慕已久,而在 Web 2.0 站点的某些点上,您会寻求某些工具,用甚至站点创建者都没有预见到的方法获得站点功能。对于 del.icio.us 来说,有很多这样的工具。开始时,站点的创建者提供他们自己的一些工具,从可用于在其他站点上显示您网络中的帖子的标记到浏览器工具栏。此外,一百多个第三方工具覆盖了您能想像到的 del.icio.us 的大多数用途,大多数,但并非全部,所以可以这样归纳,Web 2.0 站点的重要性就在于您可以突破编译器或解释程序,创建您自己的特性。
Web 提要:便宜的 API
del.icio.us 的官方 API 使用 HTTP 以及 SSL 和身份验证。但是如果您只需要读访问,那么可以选择整体上采用 Web 2.0 的更为官方的 API:Web 提要。您可以访问用户(http://del.icio.us/rss/<username>)、标记(http://del.icio.us/rss/<tag>)或者两者组合(http://del.icio.us/rss/<username>/<tag>)的 Web 提要。那么问题只在于解析 Web 提要以提取所需信息。清单 1 提供了一个示例。它是 Python 代码,该代码发送包含前一天 del.icio.us 提要条目的电子邮件。
清单 1. 用于发送前一天 del.icio.us 帖子的电子邮件的代码
import time
import smtplib
from email.MIMEText import MIMEText
from datetime import date, timedelta
import amara
#The base URI for all tags
TAGBASE = 'http://del.icio.us/tag/'
#Set FEEDS to customize which feeds you want to monitor
FEEDS = ['http://del.icio.us/rss/uche', 'http://del.icio.us/rss/popular']
FROM = 'del.icio.us@example.com'
TO = 'user@example.com'
SMTPHOST = 'localhost'
#Compute the date string for yesterday in ISO-8601 format
yesterday = (date(*time.gmtime()[:3]) - timedelta(1)).isoformat()
message_text = u''
#Using Amara. Easy to just grab the RSS feed
for feed in FEEDS:
doc = amara.parse(feed)
message_text += u'\n' + unicode(doc.RDF.channel.title) + u'\n\n'
current_items = [ item for item in doc.RDF.item
if unicode(item.date).startswith(yesterday) ]
for item in current_items:
#Get the properties of the link, defaulting to empty string
title = unicode(getattr(item, 'title', u''))
href = unicode(getattr(item, 'link', u''))
desc = unicode(getattr(item, 'description', u''))
creator = unicode(getattr(item, 'creator', u''))
message_text += u'<%s>--"%s" (from %s)\n'%(href, title, creator)
message_text += desc + '\n'
#Be sure to handle Unicode by encoding to UTF-8
msg = MIMEText(message_text.encode('utf-8'))
#Set message metadata
msg['Subject'] = u'del.icio.us bookmarks for %s\n' % yesterday
msg['From'] = FROM
msg['To'] = TO
#Send the message via the specified SMTP server
s = smtplib.SMTP()
s.connect(SMTPHOST)
#s.login(SMTP_USERNAME, SMTP_PASSWORD) #If login is necessary
s.sendmail(FROM, [TO], msg.as_string())
s.close()
|
该代码使用 Amara XML Toolkit(请参阅 参考资料)下载和解析 Web 提要(del.icio.us 使用 RSS 1.0 作为其 Web 提要格式)。示例中的两个提要一个用于我自己的用户,一个用于 popular 标记。for 循环遍历提要,查找所需日期的条目,并提取几个字段以构建到 message_text 中积累的消息文本中。循环体之后的行实际上是就是用于发送该消息。
正式的 API
如果您希望能够编辑条目,或者以任何方式访问那些尚未为您打包到 Web 提要中的数据,则您必须使用官方 API,它基于身份验证和加密的 HTTP。这些出色的 HTTP 特性的秘密就是 Python 模块 urllib2。我不会提供使用官方 API 的全部 Python 示例,原因是在 Web 上可以轻松找到这些示例。但是我会提到,每当使用 Web 2.0 站点 API 时,您必须始终注意查询频率不要太高。原因是 del.icio.us API 页面提到了以下内容:
请在两次查询之间至少等待一秒钟,否则可能会自动控制您的速度。如果您发布一个库以访问 API,则必须做到这一点。
该页面还包含其他警告,并且大多数警告适用于任何免费的、开放的 Web API,因此,花时间去关注那些能使您成为优秀 Web 开发者公民的惯例是值得的。
在 JavaScript 中使用 del.icio.us
如果您使用 ECMAScript(有时称为 JavaScript)编写使用 del.icio.us 的工具,则有另外一个进行读访问的选择,它与 Web 提要类似。到目前为止,大多数 Web 开发人员都熟悉 Asynchronous JavaScript with XML(Ajax)。XML 部分表示在网络中传递信息的方法,但是 XML 不是必需的(有关详细信息,请参阅 参考资料)。另一种受欢迎的格式是 JavaScript Object Notation(JSON),该格式的优点是,与 XML 相比,使用 ECMAScript 解析更容易。一些 del.icio.us JSON 提要类似于本文中以前使用过的 Web 提要。当您访问 URL(如 http://del.icio.us/feeds/json/<username> 和 http://del.icio.us/feeds/json/<tag>)时,您得到最近条目的 JSON 表示。清单 2 是包含从 del.icio.us 中加载 JSON 提要的 ECMAScript 的网页的一个小例子。
清单 2. 用于在网页上显示最新的 del.icio.us 帖子的代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
<title>Bookmarks from del.icio.us</title>
<script type="text/javascript"
src="http://del.icio.us/feeds/json/uche?count=10">
//Loads JSON from del.icio.us, which evaluates to an an array: Delicious.posts
</script>
<script type="text/javascript">
//Set up asynchronous display of images
function showImage(img){ return (function(){ img.style.display='inline'; }) };
function showBookmarks()
{
var ul = document.createElement('ul');
//Process each item in the del.icio.us JSON feed
for (var i=0, post; post = Delicious.posts[i]; i++) {
var li = document.createElement('li');
var a = document.createElement('a');
var img = document.createElement('img');
a.style.marginLeft = '20px';
img.style.position = 'absolute';
//Don't display image at first: will be asynchronously turned on
img.style.display = 'none';
img.height = img.width = 16;
//Raw string processing to get the URL of the bookmark icon
img.src = post.u.split('/').splice(0,3).join('/')+'/favicon.ico';
img.onload = showImage(img);
a.setAttribute('href', post.u);
a.appendChild(document.createTextNode(post.d));
li.appendChild(img);
li.appendChild(a);
ul.appendChild(li);
}
//No bullet markings for list items
ul.style.setProperty('list-style', 'none', 'important');
//Replace a targeted portion of initial content with the constructed list
var removeTarget = document.getElementById('removeTarget');
var updateTarget = document.getElementById('updateTarget');
updateTarget.removeChild(removeTarget);
updateTarget.appendChild(ul);
}
</script>
</head>
<body id='updateTarget'>
<h2>Bookmarks from del.icio.us</h2>
<p id='removeTarget'>
<a href="javascript:showBookmarks()">Click here to load addresses</a>
</p>
</body>
</html>
|
此 HTML 包括两个脚本。第一个脚本只是用于检索 JSON 的 del.icio.us 链接。所得到的对象现在对页面上的其他脚本都是可用的。第二个脚本由主 HTML 页面上的链接触发。它读取 JSON 并使用 DOM 指令构建要在页面中包含的列表。图 2 是单击所选择的 Click here to load addresses 链接时所产生的页面的一部分。
图 2. 自动加载的具有 del.icio.us 条目的网页
结束语
开放而灵活的 Web API 以及由用户上传、在用户网络中维护的内容这两者的结合是 Web 2.0 中 2.0 的真正意义所在。Internet 及其用户正在从那种受到严格控制的、从发布者到阅读者的单向信息流,迁移到发布者与其用户群之间协作的信息 Web。对此类开发比较乐观的观点认为,这样的迁移几乎与推动欧洲伟大的文艺复兴运动中的积极因素一样重要。不管这是不是可笑的夸张,它对于每个 Web 架构师理解新技术和新惯例来说都是非常重要的,原因是 Web 必然会向着协作性更强的方向发展。在此专栏中,我将以引领 Web 2.0 潮流的那些网站为上下文,观察这些技术和惯例。
参考资料 学习
获得产品和技术
讨论
关于作者
对本文的评价
|