用python和redis打造短网址服务

这篇文章的启发,用python+redis实现了文中的短网址服务。其中使用了web.py作为web框架,redis作为后台存储。部署在dotcloud上面。访问http://81aca6aa.dotcloud.com查看效果。由于使用了几个css3的效果,建议使用firefox、chrome或者ie 8以上的浏览器打开。代码放在GitHub

Web.py比django精简很多,使用起来也相对容易些。基本上对着文档,几分钟就可以写个服务出来。Django给人的感觉则是非常庞大,但是其功能是相当完善的。在框架的选择上,没有最好的,只有最适合的。这个短网址的服务不需要太复杂的功能,而且仅仅是作为一个demo写来玩玩而已,就选择了web.py。

wsgi.py

[cc lang=”python” line_numbers=”true”]
import web
import random
import string
import redis
import urlparse

render = web.template.render(‘templates/’)
urls = (
‘/’, ‘index’,
‘/(.*)’, ‘redirect’,
)

app = web.application(urls, globals())

r= redis.Redis(host=’d6d77854.dotcloud.com’, port=8603, password=”6Mb3Y1IzxFaqmjM0CB4k”, db=0)
#r= redis.Redis(host=’localhost’, port=6379, db=0)

class index:
def GET(self):
return render.index(url=None, shortcode=None)

def POST(self):
i = web.input()
url = i.url
if urlparse.urlparse(url)[0] == ” and urlparse.urlparse(url)[1] == ”:
return render.index(url=None, shortcode=None, err=”error”)
else:
shortcode = r.get(“shortcode:%s” % url)
print ‘shortcode:%s’ % shortcode
if shortcode == None:
while True:
shortcode = ”.join(random.choice(string.letters + string.digits) for x in range(6))
if r.get(“url:%s” % shortcode) == None:
r.set(“url:%s” % shortcode, url)
r.set(“shortcode:%s” % url, shortcode)
break
return render.index(url=url, shortcode=shortcode)

class redirect:
def GET(self, shortcode):
url = r.get(“url:%s” % shortcode)
if url != None:
raise web.seeother(url)

application = app.wsgifunc()

if __name__ == “__main__”:
app.run()
[/cc]
整个应用很简单,用户输入url,点击shorten按钮之后,先在redis中查询,如果已经有此url对应的短网址,取出来呈现给用户。否则生成一个6个字符的随机码,并写入redis。

第7行定义了一个render。web.template.render函数将使用的模板的根目录作为参数。这样render.hello调用的就是templates目录下面的hello.html。web模板是一种很方便的展示内容的方法。一个模板中大部分都是html,只有小部分是模板语言。通过模板语言可以实现一些控制结构,比如条件、循环,还可以进行变量替换等等。短连接应用所使用的模板在这里。webpy自身的模板语言类似于python,也是严格区分代码的缩进,这点要格外注意。另外webpy还支持mako模板语言

8-11行指明了整个服务的url结构。其中第9行表示对http://81aca6aa.dotcloud.com/的访问将由index类来处理。第10行中使用了正则表达式,这样写表示无论http://81aca6aa.dotcloud.com/这个地址后面加什么参数,比如http://81aca6aa.dotcloud.com/KpigS2,这样的访问都由redirect类来处理。这样做的原因是当用户访问像http://81aca6aa.dotcloud.com/KpigS2这样的地址时,目的是跳转到最初的长url。

index类中包含了两个函数,GET和POST,分别用来处理不同的http请求。收到GET请求时,只要将页面展示给用户即可。而POST请求则是用户提交了长url才收到的,这时应该做的,首先是检测Url是否合法(通过urlparse)。如果合法,再进行下面的流程。在redis中使用了两种key,一种是”url:http://amazingjxq.com/”这样,其value为对应的6字符随机码,另一种是”shortcode:6cxkvg”这样,其value为对应的原始url。如果不想通过两个key来记录,可以使用redis的hash类型。

redirect类只有处理GET请求的函数。当用户访问短网址时,只要根据随机码,从redis中取出原始url,然后将用户重定向到原始url即可。

目前只是实现了最简单的短网址功能。像bitly这样专业的短网址服务,还提供了很详细的统计以及生成qr code的功能。希望可以很快实现这些。

另外,现在越来越觉得,决定一种语言是好是坏,它的生态环境也是一个很重要的因素。完善的python程序库,极其方便的pip,大大提高了python的易用性。

发表评论

电子邮件地址不会被公开。 必填项已用*标注