一个显示当前日期时间的简单网页代码
#!/usr/bin/env python3
import os
date = os.popen("date").read()
html = f"""
<html>
<body>
<p style='color:#ff0000'>
{date}
</p>
</body>
</html>
"""
print(html)
解释一下里面的语法:
第1行是Shell脚本的声明,告诉操作系统应该在哪里找执行这个脚本的命令:
#!/usr/bin/env python3
下面两句是调用系统命令并获取结果。我们可以在Linux的Shell里运行date命令也看到这个结果。date还可以替换成别的Linux命令。特别注意不要把未经过滤的用户输入字符串作为系统命令运行,这会让系统被轻易地入侵。
import os
date = os.popen("date").read()
三个双引号括着的内容表示多行字符串。前面加个f表示字符串里面可以插入Python变量(用{}括起来)。
Python代码里的那段多行字符串是HTML语言的语法。其中style='color:#ff0000'又是CSS语法。CSS是用来控制网页外观的语言。这一句表示把字体颜色设置成RGB(R for Red红色,G for Green绿色,B for Blue蓝色)值为(255, 0, 0)。
在Web开发中,Python属于后端部分,在服务器运行。HTML、CSS属于前端部分(不过内容还是要从服务器获取),在浏览器运行。前端部分通常还有JavaScript,用来控制网页前端的动态逻辑。比如说,这个时间其实可以用JavaScript实现,并且做到像时钟那样一秒改变一次(并且不需要每秒都访问服务器)。后端部分通常还有SQL(比如MySQL)语言来操作数据库。因此,做一个简单的网站通常需要懂5种编程语言以及下面介绍的简单Linux操作。
把Python文件上传到服务器运行
如果是Linux系统,进入到要上传的Python文件所在目录。然后运行scp命令上传到服务器:
$ scp date.py hrx@eguidedog.net:web/
scp是一个把本地文件复制到服务器(也可反过来)的命令。eguidedog.net是服务器的域名。hrx是服务器上事先创建的用户名。hrx在服务器上的用户目录是/home/hrx。我在服务器里配置了网页子目录hrx指向/home/hrx/web的符号链接,放到/home/hrx/web里的*.html, *.py文件都可以通过"https://eguidedog.net/hrx/文件名"来访问。
如果是Windows系统,使用WinScp软件进行上传,上传的格式使用文本方式,不要使用二进制方式。这是因为,Windows的换行符号(\r\n,又称CRLF)和Linux的(\n,又称LF)是不同,而Python程序对缩进换行的解释是会影响语意的。WinScp在传输文本文件的时候会自动把换行符转换成Linux格式。随便提一下,Mac系统的换行符是\r,又称CR。三大操作系统的换行符都是不同的。
上传完后就可以在下面网址访问运行该Python程序了:
https://eguidedog.net/hrx/date.py
编写多步交互的网页
上面的网页没有交互,不能像命令行里执行input获取用户输入然后给出反馈。下面以一个例子解释网页怎样实现多步交互:https://eguidedog.net/hrx/morse.py
#!/usr/bin/env python3
# 启用CGI调试,当出错时会给出详细信息
import cgitb
cgitb.enable()
import string, random, urllib.parse, sys
# JSON是一种Web中保存、传输、显示用的常用的格式
import json
# 摩斯密码映射表
morseCode2Letters = {
".-": "A",
"-...": "B",
"-.-.": "C",
"-..": "D",
".": "E",
"..-.": "F",
"--.": "G",
"....": "H",
"..": "I",
".---": "J",
"-.-": "K",
".-..": "L",
"--": "M",
"-.": "N",
"---": "O",
".--.": "P",
"--.-": "Q",
".-.": "R",
"...": "S",
"-": "T",
"..-": "U",
"...-": "V",
".--": "W",
"-..-": "X",
"-.--": "Y",
"--..": "Z"
}
# 把上面的字典反过来
morseLetter2Codes = dict(zip(morseCode2Letters.values(), morseCode2Letters.keys()))
def genRandomLetters(length):
letters = string.ascii_uppercase
return ''.join(random.choice(letters) for i in range(length))
def translateLetters2MorseCode(letters):
translatedMorseCodes = ""
for letter in letters.upper():
if letter in morseLetter2Codes:
translatedMorseCodes += morseLetter2Codes[letter] + " "
return translatedMorseCodes
# 获取网页提交过来的参数
queryString = sys.stdin.read()
# 返回格式示例如下:{'answer': ['ABCDE'], 'code': ['AABBC']}
# 注意value值是一个列表,不是字符串,需要再取下标0的元素才能获取字符串值
values = urllib.parse.parse_qs(queryString)
if 'answer' in values:
answer = values['answer'][0]
else:
# 如果答案为空,重新生成
answer = genRandomLetters(5)
# 查出莫斯电码,输出给用户翻译
question = translateLetters2MorseCode(answer)
# 这里input的name值要和上面values里的值对应
# 我们把答案保存在一个用户看不见的隐藏字段里。但是懂技术的用户可以在浏览器查看这个答案。
# 更好的方式是通过session把答案保存在服务器的数据库或文件里,但这要复杂一些。
inputForm = f"""
<form method="POST">
<input type="hidden" name="answer" value="{answer}">
<input type="text" name="code">
<input type="submit" value="提交">
</form>
"""
# 判断用户是否答对了
result = ''
yourAnswer = ''
# 获取用户的答案,并过滤空白字符
if 'code' in values:
code = values['code'][0].strip().replace(' ', '')
yourAnswer = '您的答案是:' + code
if code == answer:
result = '<p>答对了!</p><p><a href="">重新开始</a></p>'
inputForm = '' # 答对了就不再显示提交表单
else:
result = '<p>答错了:(</p>'
# 输出到浏览器
print(f"""
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<h1>翻译莫斯电码</h1>
<p>参考:{json.dumps(morseCode2Letters)}</p>
<p>{question}</p>
<p>{yourAnswer}</p>
<p>{result}</p>
{inputForm}
</body>
</html>
""")
评论