tornado与 django、flask的5点区别:


① 改了后台代码后不自动重新运行,要点击运行窗口的Rerun;

② 运行窗口不自动显示127.0.0.1:端口号,可print一个,或在浏览器地址栏手输;

③最新版的PyCharm,New Project列表中,目前仍无自动创建tornado的模板;

④ Python文件,默认 和html文件在同个目录下,或在路由的后面指定templates和static文件夹。

⑤html模板中: 字典用d['key'],而非d.key; 判断和循环的结尾,都是 {% end %},而 另俩web框架则是用 {% endif %}、{% endfor %}、 {% endwith %}

****************************************分割线****************************************

tornado之狼人杀:

文件夹template s(和django、flask的模板文件夹的名称保持一致),和 文件 tornado之狼人杀.py平级,其内有个 文件 index之狼人杀.html


tornado之狼人杀.py:


from tornado import web, httpserver, ioloop
import random

playerSetting={
    8:{'狼人':3,'预言家':1,'女巫':1,'猎人':1,'平民':2},
    9:{'狼人':3,'预言家':1,'女巫':1,'猎人':1,'平民':3},
    10:{'狼人':4,'预言家':1,'女巫':1,'猎人':1,'平民':3},
    11:{'狼人':4,'预言家':1,'女巫':1,'猎人':1,'平民':4},
    12:{'狼人':4,'预言家':1,'女巫':1,'猎人':1,'平民':5},
}
ROOM=set(['%0.4d' %x for x in range(3)])    #房间号随机减,要用集合的pop()
usingRoom={}    #暂未让此变量发挥作用

class IndexHandler(web.RequestHandler):
    def get(self, *args, **kwargs):
        context = dict(setting='', room='', roomNum='')
        self.render('index之狼人杀.html', **context)

    def post(self, *args, **kwargs):
        playerNum= int(self.get_argument(' num'))
        if playerNum in range(8,13):
            if len(ROOM):    #若还有空房间
                roomNum=ROOM .pop()
                setting = playerSetting[playerNum]
                room=[]
                for role,num in setting.items():
                    for i in range(num):
                        room.append([role,None])
                random.shuffle(room)
                usingRoom[roomNum]=room
                context=dict(setting=setting,roomNum=roomNum,room=room)
                self.render('index之狼人杀.html',**context)
            else:
                self.write(' <h1 style="color: red">房间已满。。。。 </h1>')
        else:
            self.write(' <h1 style="color: red">请输入正确的玩家人数。。 </h1>')

app = web.Application([
    (r'/', IndexHandler),
], **{'template_path':'template s','static_path':'static'})

if __name__ == '__main__':
    httpServer = httpserver.HTTPServer(app)
    httpServer.listen(8080)
    print('http://127.0.0.1:8080')
    ioloop.IOLoop.current().start()

***************分割线***************

index之狼人杀.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>狼人杀</title>
</head>
<body>
{% if not roomNum %}
    <form action="/" method="post">
        <p>请输入要分配身份的玩家人数(不含法官)</p>
        <input type="text" name=" num" placeholder="请输入8~12的一整数">
        <input type="submit" value="创建房间">
    </form>
{% else %}
    <h1 style="color: red">狼人杀面杀网页版</h1>
    <h2>房间号码:{{roomNum}}</h2>
    <p>游戏配置:{{setting}}</p>
    <table>  <!--tr是tableRow,th是tableHead,td是tableData-->
        <tr><th>角色</th><th>玩家</th></tr>
        {% for player in room %}
            <tr><td>{{player[0]}}</td><td>{{player[1]}}</td></tr>
        {% end %}
    </table>
{% end %}
</body>
</html>

****************************************分割线****************************************

在线抽奖系统:


tornado之在线抽奖.py:

from tornado import web, httpserver, ioloop
import random

flag = True
data = {}  # 模拟数据库
userInfo = open('userInfo.txt', ' a')
luckNum = random.randint(1, 4)
context={}
context['luckNum']=luckNum

class IndexHandler(web.RequestHandler):
    def get(self, *args, **kwargs):
        temp = {'status': '', 'myNum': '', 'info': ''}
        self.render('index之在线抽奖.html', **dict(context, **temp ))

    def post(self, *args, **kwargs):
        global flag
        phone = self.get_argument('phone', default=None).strip().replace(' ', '')
        qq = self.get_argument('qq', default=None).strip().replace(' ', '')
        if len(phone)==11 and len(qq)>4 and phone.isdigit() and qq.isdigit():
            if flag:  # 君子协定:若奖品已被抽走,后参与用户不可能中奖,则不能收集其信息
                if phone in data:
                    temp = {'status': '','myNum':'','info': '对不起,一个手机号只能抽1次'}
                    self.render('index之在线抽奖.html',**dict(context,**temp))
                else:
                    userInfo.write(f'抽奖用户的电话:{phone},QQ:{qq} \n')
                    userInfo.flush()
                    data[phone] = qq    #放在内存而非如上文般写入文件,所以字符尽量少
                    myNum = random.randint(1, 4)
                    if myNum == luckNum:
                        with open('luckUser.txt', 'a') as f:
                            f.write(f'中奖用户的电话:{phone},QQ:{qq}\n')
                        flag = False
                        temp = {'status': True,'myNum':myNum,'info': f'恭喜{phone},中奖啦'}
                        self.render('index之在线抽奖.html', **dict(context,**temp))
                    else:
                        temp = {'status': '','myNum':myNum,'info': '谢谢参与,没能中奖'}
                        self.render('index之在线抽奖.html',**dict(context,**temp) )
            else:
                temp = {'status': '','myNum':'','info': '很遗憾,奖品已被抽走'}
                self.render('index之在线抽奖.html',**dict(context,**temp) )
        else:    #status和myNum的值要用 '',因为 False和 None都会在html界面显示出来
            temp = {'status': '','myNum':'','info': '请输入正确的手机和QQ号'}
            self.render('index之在线抽奖.html',**dict(context,**temp) )


app = web.Application([
    (r'/', IndexHandler),
])    #只1个模板,就不写二参了:**{'template_path':'templates','static_path':'static'}

if __name__ == '__main__':
    httpServer = httpserver.HTTPServer(app)
    httpServer.listen(8080)
    print('http://127.0.0.1:8080')  #tornado的运行窗口无链接,则print一个
    ioloop.IOLoop.current().start()

***************分割线***************

index之在线抽奖.html:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>在线抽奖</title>
</head>
<body>  <!--让一行标题内出现两种字体颜色,可用 行内分区标签span-->
<h1>电脑随机号:<span style="color: goldenrod">{{luckNum}}</span></h1>
<form action="/" method="post">
    手机:<input type="text" name="phone" style="width: 130px"><br>
    QQ:<input type="text" name="qq" style="width: 135px" >
    <br><br>
    <input type="submit" value="开始抽奖">
</form>
<br>
{% if status %}
    <h1 style="color: goldenrod">我的随机号:{{myNum}}</h1>
    <h1 style="color: goldenrod">{{info}}</h1>
{% else %}
    {% if myNum %}
        <h1 style="color: blue">我的随机号:{{myNum}}</h1>
        <h1 style="color: blue">{{info}}</h1>
    {% else %}
        <h1 style="color: red">{{info}}</h1>
    {% end %}
{% end %}
</body>
</html>

****************************************分割线****************************************

随机生成6个红球号码+1个蓝球号码:


tornado之红蓝球.py:

from tornado import web,httpserver,ioloop
import random

def createBall():
    result = []
    redBallList=list(range(1,34))
    blueBallList=list(range(1,17))
    for x in range(6):
        random.shuffle(redBallList)
        redNum=redBallList[:6]
        # blueNum=[x for x in blueBallList if x not in redNums]  #红、蓝球不重号
        result.append({'redNum':redNum , 'blueNum': random.choice(blueBallList)})
    return result

def getLuckNum(button):
    if button==' 随机1注':
        return [createBall()[0] ]    #原本是{},套个[],使得return的都统一为[{},]
    elif button== '随机5注':
        return createBall()[1:]

class IndexPageHandler(web.RequestHandler):
    def get(self, *args, **kwargs):
        # self.write('hello,world!')  #传文字或网页源代码用 write;传html文件也是用 render
        self.render('index之红蓝球.html', rows= '')

    def post(self, *args, **kwargs):
        button=self .get_argument(' submit')  #属性name为submit的标签,其value属性的值
        luckNum=getLuckNum(button)
        self.render('index之红蓝球.html', rows=luckNum)

app=web.Application([
    (r'/', IndexPageHandler),
])

if __name__ == '__main__':
    httpServer=httpserver.HTTPServer(app)
    httpServer.listen(8080)
    ioloop.IOLoop.current().start()

***************分割线***************

index之红蓝球.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>红蓝球</title>
</head>
<body>
    <h1 style="color: red">红蓝球</h1>
    <form action="/" method=" post">
        <input type="submit" value=" 随机1注"  name=" submit">
        <input type="submit" value=" 随机5注"  name=" submit">
    </form>
    <br>
    <div>
        {% if rows %}
            {% for row in rows %}
                {% for redNum in row['redNum'] %}
                    <span style="color: red">{{redNum}}</span>
                {% end %}
                <span style="color: blue">{{row['blueNum']}}</span><br>
            {% end %}
        {% end %}
    </div>
</body>
</html>

****************************************分割线****************************************

51job:


spider之无忧job.py:

import requests,re
#使用时,先把全角的<全部替换为半角的
pattern=re.compile('class="el">.*?title="(.*?)".*?title="(.{2,15})有限公司".*?http://\
(.*?)".*?"t3">(.*?)<.*?"t4">(.*?)<.*?"t5">(.*?)<',re.S)

class JobSpider:
    def __init__(self):
        self.session=requests.session()

    def download(self,url):
        response=self.session.get(url)
        response.encoding='gbk'
        return response.text

    def run(self,word):
        page=1
        url=f'http://search.51job.com/list/030200,040000,030800,\
        000000,0000,00,9,99,{word},2,{page}.html'
        html=self.download(url)
        if html:
            return pattern.findall(html)

# spider=JobSpider()
# print(spider.run('python'))

***************分割线***************

tornado之无忧job.py :


from tornado import web,httpserver,ioloop
import time
from spider之无忧job import JobSpider

startTime=time.time()
data={}

class IndexHandler(web.RequestHandler):
    def get(self, *args, **kwargs):
        self.render('index之无忧job.html', rows= '')

    def post(self, *args, **kwargs):
        job=self.get_argument(' job', None)
        if job: #若30分钟内没搜索过这个职位
            if job not in data or time.time()-startTime>60*30:
                spider=JobSpider()
                rows=spider.run(job)
                data[job]=rows  #缓存30分钟
                self.render('index之无忧job.html', rows=rows)
            else:
                self.render('index之无忧job.html', rows=data[job])

app=web.Application([(r'/',IndexHandler),])

if __name__ == '__main__':
    httpServer=httpserver.HTTPServer(app)
    httpServer.listen(8080)
    ioloop.IOLoop.current().start()

***************分割线***************

index之无忧job.html :


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>51job</title>
</head>
<body>
    <form action="/" method=" post">
        <input type="text" name=" job" placeholder="输入要搜的职位如:Python" style="width: 200px">
        <input type="submit" value="搜索">
    </form>
    {% if rows %}
        <br>
        <table>
            <tr>
                <th>职位名</th><th>公司名</th><th>公司网址</th>
                <th>工作地点</th><th>薪资</th><th>发布时间</th>
            </tr>
            {% for row in rows %}
                <tr>
                    {% for item in row %}
                        <td>{{item}}</td>
                    {% end %}
                </tr>
            {% end %}
        </table>
    {% end %}
</body>
</html>