之前写过一篇关于12306信息查询页面的文章,今天重新整理一下,我用的是flask+redis,由于数据十几万都放在mysql里,即使创建索引,我的vps还是有点吃紧。
redis可以做storage和cache,由于这些数据不是很重要,丢了大不了再导入一次,但是我们更在乎的是查询效率,所以redis做storage是很好的选择。
首先把文件里的数据导入redis,raw文件里的数据是以下格式的,文件名为result.txt
# -*- coding: utf-8 -*-
import redis
import time
start = time.clock()
redisClient = redis.StrictRedis(host='localhost',port=6379,db=0,password='redis@123')
f = open('result.txt','r')
while True:
line = f.readline()
if not line:
break
lines = line.replace("\n","").replace("\r\n","").split("----")
redisClient.hset(lines[0],"id",lines[0])
redisClient.hset(lines[0],"name",lines[1])
redisClient.hset(lines[0],"password",lines[2])
redisClient.hset(lines[0],"email",lines[3])
redisClient.hset(lines[0],"phone",lines[4])
f.close()
end = time.clock()
print "used:", end -start
13w数据不到一分半钟。。。
这里我的key都是id也就是***好,其它都是hash的数据结构形式存储的。redis的优点之一就是可以支持丰富的数据结构。登录redis,执行keys *看一下
ok,数据有了,那么开始上flask了,代码如下:
# -*- coding: utf-8 -*-
from flask import Flask, request, render_template, jsonify, json
import redis
app = Flask(__name__)
@app.route('/api/<id>', methods=['GET'])
def scan(id):
redis_client = redis.StrictRedis(host='127.0.0.1',port=6379,db=0,password='redis@123')
get_key = redis_client.keys(id)
if not get_key :
json_result = {'id' : None}
return json.dumps(json_result,ensure_ascii=False)
else:
get_key = redis_client.hmget(id,'name','password','email','phone')
json_result = {'id' : str(id),
'name' : get_key[0],
'pass' : get_key[1],
'email': get_key[2],
'phone': get_key[3]
}
return json.dumps(json_result,ensure_ascii=False)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port = 8080, debug=True)
我们要查询哪个用户就把传参数给flask封装的api,这就是给接口传参即可。
什么是接口?看下面的说明理解一下。
在浏览器里输入api地址,随便传一个不存在的参数,也就是***号。
接口返回值为null
如果传参是存在的,就会有正确的返回值。
最后就是前端页面展示了,我用的是bootstrap和jquery的ajax插件。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{{ url_for('static', filename='icon/favicon.ico') }}">
<title>12306</title>
<!-- Bootstrap core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="{{ url_for('static', filename='css/jumbotron.css') }}" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Main jumbotron for a primary marketing message or call to action -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">12306</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">12306网站用户信息泄漏查询</a>
</div>
</nav>
<script src="{{ url_for('static', filename='js/template.js') }}"></script>
<div class="container" style="padding-top: 48px;">
<div class="bs-callout bs-callout-info mt0">
<div class="alert alert-danger">
<p><h4>本系统程序仅为用户确认个人信息是否已经泄露,切勿用作非法目的,否则一切后果自负!</h4></p>
</div>
</div>
<div class="row" style="margin:0;min-height:600px">
<div class="jumbotron search-box">
<p>请输入关键字:</p>
<div class="input-group">
<input placeholder="***号"
type="text" name="id" id="keyword" class="form-control">
<span class="input-group-btn scan-but-span">
<button class="btn btn-success" onclick="scan()" type="button">查找一下</button>
</span>
</div>
<div class="input-group mt15">
<script type="text/javascript" src="
</div>
<div id="scan-result-box">
</div>
</div>
<div id="container" class="row" style="hight:280px">
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
<script>
var geetest_passed = false;
var selectorObj;
function gt_custom_ajax(result, selector) {
selectorObj=selector;
geetest_passed = result;
}
var keyword = "";
function scan(){
keyword = $.trim($("#keyword").val());
if(keyword==''){
alert('请输入***');
$("#keyword").focus()
return false;
}
if(!geetest_passed) {
alert("请滑动图片进行验证!")
return false;
}
$.ajax({
type:'get',
dataType:'json',
url:' //本地的ip或域名
success:function(data){
if(!data.id){
alert('恭喜!您的信息没有被泄露!');
return false;
}
var re="<ul>";
re+="<li>姓 名:"+data.name+'</li>';
re+="<li>***:"+data.id+'</li>';
re+="<li>E-mail:"+data.email+'</li>';
re+="<li>手机号:"+data.phone+'</li>';
re+="</ul>"
$('#container').html(re)
},
error:function(){
alert('您的信息不存在!')
}
})
}
</script>
</body>
</html
好了,启动webserver,看看页面查询情况:
输入一个***号,如果存在,页面就会返回
如果不存在,js就会alert一个弹框。
是不是还比较简单,我的好友强子想了解一下如何构建,所以分享一下。。。