Python3_CGI编程踩坑日记

Hard-start

这是学习Python的第六天,也是进入Python高级编程的第一天,嗯,对,然后我就遇见了Big Problem,甚至到现在都还有一个问题没有解决。

Problem I met

  1. Apache的安装问题

在得之要使用Apache之后,我直接就百度Apache,然后再官网首页

官网1

结果下载下来直接用不了,解压了发现文件不对。然后一搜教程才发现文件下载错了。

应该在这里下载:

官网2

终于完成填了第一个坑!

  1. Apache配置问题

要启用CGI,必需修改配置文件。而这个配置不仅仅是是一个地方,是n个地方:

  1. ServerRoot配置

ServerRoot “” 主要用于指定Apache的安装路径,此选项参数值在安装Apache时系统会自动把Apache的路径写入。Windows安装时,该选项的值为Windows安装的路径,Linux安装时该选项值为编译时选择的路径

找到:

Define SRVROOT "${SRVROOT}"
ServerRoot "${SRVROOT}4"

改为:

Define SRVROOT "D:\web\Apache24"
ServerRoot "D:\web\Apache24"

其中”${SRVROOT}”应改为你你安装Apache的目录。

  1. Listen 配置

Listen主要侦听web服务端口状态,默认为:80,即侦听所有的地址的80端口,注意这里也可以写成IP地址的侦听形式,不写即默认的地址:0.0.0.0

找到:

Listen:80

改为:
Listen:8080

一般不为80,因为容易占用,改为其他好一点。比如我改为8080。

  1. CGI配置

找到:

AddHandler cgi-script .cgi .pl 

改为:

AddHandler cgi-script .cgi .pl .py

这里是增加对Python的支持。

找到:

<Directory "/${SRVROOT}">
    AllowOverride none
    Require all denied
</Directory>

改为:

<Directory "D:\web\Apache24\cgi-bin">
    AllowOverride None
    Options Indexes FollowSymLinks ExecCGI
    Require all granted 
    Require host ip
</Directory>

注意这里/${SRVROOT}任然还是Apache的安装地址。

  1. Python解释器

我就这么按照runoob上代码粘贴下来,like this:

#!/usr/bin/python3

print ("Content-type:text/html")
print ()                             # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! 我是来自菜鸟教程的第一CGI程序</h2>')
print ('</body>')
print ('</html>')

然后就出现了500错误,下面是log里的提示:

[Mon Jan 14 11:31:58.626473 2019] [cgi:error] [pid 3624:tid 1196] (OS 2)系统找不到指定的文件。  : [client ::1:52212] couldn't create child process: 720002: hello.py

[Mon Jan 14 11:31:58.660452 2019] [cgi:error] [pid 3624:tid 1196] (OS 2)系统找不到指定的文件。  : [client ::1:52212] AH01223: couldn't spawn child process: D:/web/Apache24/cgi-bin/hello.py

百度了半天,突然想起Apache如何载入编译器呢,然后直接百度上面代码的第一行:

#!/usr/bin/python3

然后才知道这是Linux下Python的解释器位置,我枯了。然后我找到了自己Python3的安装位置,却发现没有exe文件,我又枯了。但是用sys自己的命令:

import sys
sys.path

得到了就是这个位置。不管了,直接写吧!
于是得到了这一段代码:

#!D:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\python.exe

没错,就是这么长,不知道自己当时怎么安装的。我又枯了。

结果成功解析了!!!

但是!!!

又乱码了,检查了py文件的编码,发现py默认是utf-8啊。然后终于在网上找到了解决办法。没错,是print()函数的问题。

又大佬看print()源码使用Unicode,果然乱码了,然后引入了这一段代码:

import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')

即:将print()函数改为utf-8编码输出,终于留了一张图:

正常输出

附上正常获取text,textarea的代码,其他的都一样。

(text.html):

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<form action="/cgi-bin/text.py" method="POST" target="_blank">
<input tyep = 'text' name = 'name'/>
<textarea name="personinform">个人信息</textarea>
<input type='submit' value='提交'>
</form>
</body>
</html>

(text.py):

#!D:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\python.exe
import io
import sys
import cgi, cgitb
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
form = cgi.FieldStorage()
name = form.getvalue('name')
personinform= form.getvalue('personinform')
print ("Content-type:text/html")
print ()                             # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! 我是第一CGI程序</h2>')
print(name)
print(personinform)
print ('</body>')
print ('</html>')

下面是get从url来获取键值的方法:

#!D:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python37\\python.exe
import io
import sys
import cgi, cgitb
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
form = cgi.FieldStorage()
name = form.getvalue('name')
number = form.getvalue('number')
print ("Content-type:text/html")
print ()                             # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! 我是第一CGI程序</h2>')
print(name,number)
print ('</body>')
print ('</html>')

get方法图片

  • last problem(unsolved)

最后一个问题就是CGI的文件上传问题。由上面的代码可以知道,所有接受的数据都来自:

cgi.FieldStorage()

网上的教程都这么获得数据:

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# 获取文件名
fileitem = form['filename']

# 检测文件是否上传
if fileitem.filename:
# 设置文件路径 
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn,   'wb').write(fileitem.file.read())

message = '文件 "' + fn + '" 上传成功'

else:
    message = '文件没有上传'

但是问题在于,

fileitem.filename == none

我直接输出 fielitem

fileitem = MiniFielStorage('filename','test.txt')
#test.txt为上传的文件名

所以fileitem.filename始终为none。所以一直解决不了,查了各种资料,不过官方文档里有类似的解释,但是还是没有解决办法。明天再看吧~~~难受啊,马飞~

Powered by Hexo and Hexo-theme-hiker

Copyright © 2019 - 2024 My Wonderland All Rights Reserved.

UV : | PV :