如何用 python,Djano 生成 SEO 友好的 URL, 包含中文处理

摘要: 做技术的人,在搜索技术问题时,估计经常会搜索到一个网站:stackoverflow, 你会发现这个网站的的 url 的设计对搜索引擎来说是非常友好的, 在 url 的后面直接跟上了这篇文章的核心关键字, 很多英文习惯的用户很自然的就能搜索到这些文章. 当然  stackoverflow 是英文版的,在这方面有天然的优势。因为因为英文字母都是 acsii 码的,比较容易做到,我在用 Django 做项目的时候,也尝试了这种 url 的方式,django 严格说来是天生支持这种方式的,只是没有考虑中国用户的习惯,下面总结几种处理方式

做技术的人,在搜索技术问题时,估计经常会搜索到一个网站:stackoverflow, 你会发现这个网站的的 url 的设计对搜索引擎来说是非常友好的, 在 url 的后面直接跟上了这篇文章的核心关键字, 很多英文习惯的用户很自然的就能搜索到这些文章. 当然 stackoverflow 是英文版的,在这方面有天然的优势。因为因为英文字母都是 acsii 码的,比较容易做到,我在用 Django 做项目的时候,也尝试了这种 url 的方式,django 严格说来是天生支持这种方式的,只是没有考虑中国用户的习惯,下面总结几种处理方式:

利用 Django 的 slugify 来处理
一个简单的例子如下:

from django.template.defaultfilters import slugify
if __name__ == "__main__":
    
    # 测试英语与拼音能否处理
    myurl = slugify("what is this, could you tell me? ni neng gao su wo ma")   
    print myurl
    
    # 测试汉子是否能处理,结果是不能处理
    chinese_url = slugify("这是什么东西,你能告诉我吗?");
    print chinese_url


运行结果如下:
what-is-this-could-you-tell-me-ni-neng-gao-su-wo-ma


这说明,仅仅将英文标题生成了slug 方式,而中文完全被忽略了,原因很简单,django 的源代码里面这里就是按照 ascii 来处理的:
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
return mark_safe(re.sub('[-\s]+', '-', value))


所以,如果是中文字符是被忽略掉了。对于英文写作的人来说,这就已经足够了,但对于要写中文的来说,估计还得采用下面的方式.

采用 Firefox 里面用到的方法
这种解决方法的来源是在github上的一个开源项目: https://github.com/mozilla/unicode-slugify , 它的一个优点是,中文还是中文,仍然保留不变,英文内容做处理,看测试源码如下:
#coding:utf-8
'''
Created on 2014-5-27
@author: Administrator
'''

import re
import unicodedata

try:
    from django.utils.encoding import smart_unicode as smart_text
except ImportError:
    from django.utils.encoding import smart_text

# Extra characters outside of alphanumerics that we'll allow.
SLUG_OK = '-_~'


def slugify(s, ok=SLUG_OK, lower=True, spaces=False):
    # L and N signify letter/number.
    # http://www.unicode.org/reports/tr44/tr44-4.html#GC_Values_Table
    rv = []
    for c in unicodedata.normalize('NFKC', smart_text(s)):
        cat = unicodedata.category(c)[0]
        if cat in 'LN' or c in ok:
            rv.append(c)
        if cat == 'Z':  # space
            rv.append(' ')
    new = ''.join(rv).strip()
    if not spaces:
        new = re.sub('[-\s]+', '-', new)
    return new.lower() if lower else new

if __name__ == "__main__":
    #测试汉字是否能处理
    print slugify("这是什么东西,你能告诉我吗?")
    #测试英文拼音
    print slugify("what is this, ni neng gao su wo ma?")
    #测试中英文混合
    print slugify("这是什么东西,could you tell me?")


结果如下:
这是什么东西你能告诉我吗
what-is-this-ni-neng-gao-su-wo-ma
这是什么东西could-you-tell-me


完美的输出,中文完好,英文也符合国外用户习惯,同时完全满足SEO的 URL 规则, 但这只是一种喜欢用汉子直接显示在 url 的用户,但是就我看来,我不喜欢这样,因为不同的浏览器对汉子在url 上的解析方式不同,会有所变化.

回归 url , 用原生的ascii 码来表示url 是绝对正确的选择,但ascii 码表示 汉子兼职就像乱码,对中国用户来说估计最不友好了,而 URL 设计的标准既然是友好的,那么乱码是不可接受的。 但是,我们可以用拼音,将汉子转换成拼音显示在 URL 中,不就可以了吗, 开源世界早有人这么做了,所以不需要重造轮子,安装现有的开源库: https://github.com/iki/unidecode, 这是国人写的一个库,将常用汉子的拼音以及ascii 码之间的关系全部映射了,我们直接拿来用就好了,作者干了不少体力活,佩服中, 安装好这个库之后,测试代码如下:
#coding:utf-8
from django.utils.safestring import mark_safe
from unidecode import unidecode
import re
import unicodedata
value = unidecode("中文 URL 能生成拼音的吗?" + u"")
value = re.sub('[^\w\s-]', '', value).strip().lower()
value = mark_safe(re.sub('[-\s]+', '-', value))

print value.lower()

value = unidecode("english url, does this tool can generate it?")
value = re.sub('[^\w\s-]', '', value).strip().lower()
value = mark_safe(re.sub('[-\s]+', '-', value))
print value.lower()



结果如下;
zhong-wen-url-neng-sheng-cheng-pin-yin-de-ma
english-url-does-this-tool-can-generate-it


完美的汉语拼音与英文都能满足的结合。如果我今后做项目,估计会采用这个了。另外还有一种方式,比较适合走极端的人,我们可以用python 发请求到 google translate, 然后将翻译之后的结果得到再做处理,做法不难,有时间弄一个试试,但现在就可以想到结果,翻译出来的东西估计错误很多。所以不是很可取.

上一篇: 自定义django class based view 的一个例子
下一篇: 分享一个定制 ibm case manager widget 的ppt 文档
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号