介绍
一个基于Python-Flask框架开发的短网址生成器,数据库使用python内置的Sqlite3,直接部署即可使用,不需额外再创建数据库。同时提供短网址生成API与心灵毒鸡汤API。
[btn class="btn-info btn-rounded" url="https://surl.ztyang.com"]点击预览[/btn]
GitHub地址: https://github.com/ztyangt/shorturl
原理
简述
所谓短网址生成,并不是真正意义上的将长长的URL给变短了,它只不过是为长链接生成一个专属的短链,当我们在浏览器里访问这个短链时,再302重定向到原来的长链接。
意义:
- 易于传播,易于记住
- 生成的二维码较原链接简单
- 等等...
基于Flask实现
Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。
数据库初始化
class initDB(object):
def __init__(self, app=None):
if app:
self.init_app(app)
def init_app(self, app):
DB = SqlHelper.Connect(DB_FILE_PATH)
DB.table('shortURL').create({
'id': 'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT',
'shortID': 'TEXT NOT NULL',
'longUrl': 'TEXT NOT NULL',
'shortUrl': 'TEXT NOT NULL',
'creatTime': 'varchar(24) NOT NULL'
})
if DB.table('soup').count('id')==0:
file = open('data/soup.txt','r',encoding='utf-8')
ls = file.readlines()
DB.table('soup').create({
'id': 'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT',
'text': 'TEXT NOT NULL',
}, insert=[{'text': item} for item in ls])
DB.close()
短链生成API
@api.route('/', methods=['GET'])
def swURL():
# url = request.values.get("url")
host = f"{urlparse(request.host_url).scheme}s://{urlparse(request.host_url).netloc}/"
url = urllib.parse.unquote(request.url.split("url=")[-1])
if url == request.url:
return jsonify({"code": 400, "msg": "请输入URL"})
pattern = r'^(http|https|ftp|file)?:/{2}\w.+$'
result = re.match(pattern, url)
if result:
DB_FILE_PATH = r'data/shorturl.db'
shortDB = SqlHelper.Connect(DB_FILE_PATH)
longURL = result[0]
urlQuery = shortDB.table('shortURL').where(f"longUrl = '{longURL}'").find()
if len(urlQuery) > 0:
data = {'shortID': urlQuery[0]["shortID"], 'longUrl': urlQuery[0]["longUrl"],"shortUrl": f'{host}{urlQuery[0]["shortID"]}','creatTime': urlQuery[0]["creatTime"]}
return jsonify({"code": 200, "msg": "URL已存在","data": data })
shortID = s64(int(time.time()))
data = {'shortID': shortID, 'longUrl': longURL,"shortUrl":f'{host}{shortID}','creatTime': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
shortDB.table("shortURL").add(data)
shortDB.close()
return jsonify({
"code": 200,
"msg": "短链接创建成功!",
"data": data
})
return jsonify({"code": 400, "msg": "URL格式错误"})
这个API接口提取前端提交的长链接作为参数,然后为之生成一个专属短链ID,一并插入数据表,表结构如下所示:
关于短链ID的生成,我采用了将当前时间戳转化为64进制的方案:
table = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZαβ"
def s64(n: int):
s = bin(n)[2:]
if j := (h := len(s)) % 6:
s = "0" * j + s
return "".join([table[int(s[i : i + 6][::-1], 2)] for i in range(0, h, 6)])
长链接重定向
@route.route('/<shortID>', methods=['GET'])
def redirectUrl(shortID):
DB_FILE_PATH = r'data/shorturl.db'
shortDB = SqlHelper.Connect(DB_FILE_PATH)
urlQuery = shortDB.table('shortURL').where(f"shortID = '{shortID}'").find()
shortDB.close()
if len(urlQuery) > 0:
return redirect(urlQuery[0]['longUrl'])
return redirect(url_for('route.index'))
短网址API
- 方法: GET, POST
- 接口: http(s)://[域名]/api
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
url | 是 | string | 需要转换的长链接 |
请求返回的数据结构:
{
"code": 200,
"data": {
"creatTime": "2022-09-12 15:02:26",
"longUrl": "https://www.ztyang.com",
"shortID": "6zTC11",
"shortUrl": "http://127.0.0.1:5000/6zTC11"
},
"msg": "短链接创建成功!"
}
心灵毒汤API
- 方法: GET,
- 接口: http(s)://[域名]/soup
- 参数: 无
请求成功返回的数据结构:
{
"code": 200,
"data": {
"id": 432,
"text": "遇到闪电记得要微笑,因为那是天空在给你拍照。"
}
}
安装
这里以宝塔为例:
- 首先在宝塔软件商店里安装
python项目管理器v
- 将源码上传到宝塔任一指定的网站目录,如下图所示:
- 打开python项目管理器,填写相关安装信息:
注意:端口号需要提前打开,不然部署后会无法访问网站
- 域名映射,将域名解析到项目所部署的服务器,填写域名:
- 部署完成