通过webpy实现一个简单的相关关键词API接口

前两天的时间比较忙,没有时间做分享,所以今天给大家分享一个福利吧。如果你是做SEO的,那么这个可能对你的工作有所帮助。

前些日子有个基友找我做一个web的API接口,主要的功能如下:

  • 有自己的一个关键词词库
  • 通过http请求一个关键词,然后返回跟这个关键词最相关的N个结果

就是想这两个简单的功能,因为功能太简单,因此就没有必要用到复杂的框架(Django, flask)这些,所以就用了一个最基本的webpy实现。

效果展示
1.默认首页
默认首页
2.关键词搜索结果页(词库有点不纯洁)
关键词搜索结果页

实现过程
首先需要安装webpy以及Levenshtein,安装方法也很简单:

pip install web.py python-levenshtein

如果安装下载速度比较慢的,那么可以使用豆瓣源进行安装。对于MacOS和Linux用户可能需要root权限,这个自行添加就好。

先说一下实现思路
整个API的核心就是通过一个关键词来查找跟他相关的关键词,那么就需要到一个关键词相似度的算法来计算。由于一个词库的关键词数量可能存在很多的关键词(几万,几十万等)那么对于算法的效率要求就比较高了。这也是我没有用余弦相似度算法的原因,因为那个算法需要用到jieba分词,如果每次都对几十万的词进行分词是会崩溃的。所以这里我用了一个效率比较高,准确度还算可以的编辑距离算法,这个算法是别人优化过的,直接拿来用就好,经测试词库6W多的词基本是瞬时响应。

具体代码实现细节
先来实现根据一个关键词,返回N个相似的关键词

import Levenshtein

def match_key(key, num, library):
    """获取固定数量的相关关键词
    key: 要获取的关键词
    num: 要获取相关词的数量
    library: 关键词词库
    return: 由/分割的字符串组成的N个关键词
    """
    simi_dict_list = {lib_key: Levenshtein.jaro(key, lib_key) for lib_key in library}
    simi_list = sorted(simi_dict_list.iteritems(), key=lambda x: x[1], reverse=True)
    return "/".join([w[0] for w in simi_list[:num]])

解释一下代码:函数需要传递三个参数(要查询的关键词,要返回的关键词数量,要查询的关键词库)第一句是将关键词与通过levenshtein.jaro方法计算出来的相似度组成一个字典。然后通过sorted方法,以相似度值进行逆序排序,得到的是一个元组组成的list,最后根据参数num来设置返回多少个关键词,并通过join方法以/区分每个关键词,组成字符串返回。

web请求部分代码实现

import web

urls = (
    '/', 'Index',
)
# 关键词词库 每行一个关键词
ciku = [w.strip() for w in open("ciku.txt")]

class Index:
    def GET(self):
        web.header('Content-Type','text/html; charset=utf-8')
        key = web.input(s=None)
        num = web.input(n=None)
        if key.s is not None:
            word = key.s.encode("utf-8")
            number = int(num.n) if num.n else 3
            return match_key(word, number, ciku)
        else:
            return "欢迎使用关键词自动匹配系统!"

简单解释一下代码:
变量urls里面就是配置路由的,每行一个路由,前面表示请求路径/(首页),后面是实现这个请求的类名Index。接下来就是导入关键词的词库,每行一个关键词,文本要是utf-8编码,墙裂要求python编程过程中一直用这个编码。
后面就是实现Index这个类,因为这里我们都是get请求,所以就之定义了GET方法。接着先定义响应头的编码(不然中文响应可能会返回乱码),然后通过web.input(key=default)方法获取GET请求参数,其中key就是参数名, default就是参数默认值,我这里设置为None。通过这种方法分别获取关键词和返回数量。
接下来判断是否获取到关键词,如果获取不到,那么说明没有写对参数名或者是请求首页,这时直接返回一段话就好了。如果获取到了那么就先将关键词进行编码为utf-8的,因为获取到的是Unicode编码。然后判断是否有提供返回数量的参数,如果没有就直接默认是返回3个相关词。接下来就是直接将参数传入到之前计算相关度的函数match_key,然后返回。

启动服务部分代码
因为比较简单,所以全部放在了一个文件里面,运行服务代码如下:

if __name__ == '__main__':
    app = web.application(urls, globals())
    app.run()

这部分的代码就没啥好解析的了,if __name__ == ‘__main__’就是只有运行当前的文件才会执行下面的代码。接着就创建一个webpy的应用实例,把路由配置和全局变量传进去,最后启动应用。

运行代码
在当前代码文件夹下使用如下命令,假设文件名是index.py:

$python index.py 8000

就会看到输出http://0.0.0.0:8000/,然后再浏览器打开就看到文章前面的展示效果啦。
完整代码地址: https://github.com/brookxs/webpywebpy
学习地址:http://webpy.org/docs/0.3/tutorial.zh-cn
微信公众号:布鲁的python

发表评论

电子邮件地址不会被公开。