• head first python /chapter7 web(python 3 转 python 2.7)


    前言

    书中使用的是python3,我这里使用的是python2.7

    Web 的目录树

    webapp/
    ├── cgi-bin
    │ ├── athletelist.py
    │ ├── athletemodel.py
    │ ├── generate_list.py
    │ └── yate.py
    ├── coach.css
    ├── data
    │ ├── james.txt
    │ ├── julie.txt
    │ ├── mikey.txt
    │ └── sarah.txt
    ├── favicon.ico
    ├── images
    │ └── coach-head.jpg
    ├── index.html
    ├── simplehttp.py
    └── templates
    │ ├── footer.html
    │ └── header.html

    整体的功能

    整体的功能是创建一个网站,index.html中有个链接,链接到cgi-bin下的generate_list.py,这个cgi脚本自动生成html代码。

    Python启动本地web服务器

    由于书中使用的是python3的代码,所以自己在网上找了python2.7的代码

    simplehttp.py

    1 import BaseHTTPServer, CGIHTTPServer
    2 
    3 port = 8080
    4 
    5 httpd = BaseHTTPServer.HTTPServer(('', port), CGIHTTPServer.CGIHTTPRequestHandler)
    6 print ('starting simple_httpd on port :' + str(httpd.server_port))
    7 httpd.serve_forever()

    开启web服务,只需要用cmd进入自己网站所在的文件夹,python simplehttp.py 就可以了。本地服务器地址是localhost:8080

    index.html

     1 <html>
     2 <head>
     3 <title>Welcome to Coach Kelly's Website</title>
     4 <link type="text/css" rel="stylesheet" href="coach.css" />
     5 </head>
     6 <body>
     7 <img src="images/coach-head.jpg">
     8 <h1>Welcome to Coach Kelly's Website.</h1>
     9 <p>
    10 For now, all that you'll find here is my athlete's <a href="cgi-bin/generate_list.py">timing data</a>. Enjoy!
    11 </p>
    12 <p>
    13 <strong>See you on the track!</strong>
    14 </p>
    15 </body>
    16 </html>

    效果图如下
    index.html

    主页中的timing data链接到generate_list.py文件,在上面开启web服务的py文件执行后,timing data链接下的py会执行

    generate_list.py

    这是个自动生成html代码的py

     1 import athletemodel
     2 import yate
     3 import glob
     4 
     5 data_files=glob.glob ("data/*.txt")
     6 athletes=athletemodel.put_to_store(data_files)
     7 print (yate.start_response())
     8 print(yate.include_header("Coach Kelly's List of Athletes"))
     9 print (yate.start_form("generate_timing_date.py"))
    10 print (yate.para("Select an athlete from the list to work with:"))
    11 for each_athlete in athletes :
    12     print(yate.radio_button("which_athlete",athletes[each_athlete].name))
    13 print (yate.end_form("Select"))
    14 
    15 print (yate.include_footer({"Home":"/index.html"}))

    print (yate.include_footer({“Home”:”/index.html”}))
    这里生成的html是

    <p>
    <a href="/index.html">Home</a>&nbsp;&nbsp;&nbsp;&nbsp;
    </p>

    很奇怪按照常理相对路径应该是../index.html,在自己电脑上测试时,打开网页,a href=”/index.html” 这种是错误的,但是用python建立web服务后,这种方式也能返回主页,很奇怪。

    效果图如下
    generate_list.py生成的html代码在服务器打开的效果

    yate.py

    from string import Template
    
    def start_response(resp="text/html"):
        return('Content-type: ' + resp + '
    
    ')
    
    def include_header(the_title):
    
        with open('templates/header.html') as headf:
            head_text = headf.read()
        header = Template(head_text)
        return(header.substitute(title=the_title))
    
    def include_footer(the_links):
    
        with open('templates/footer.html') as footf:
            foot_text = footf.read()
        link_string = ''
        for key in the_links:
            link_string += '<a href="' + the_links[key] + '">' + key + '</a>&nbsp;&nbsp;&nbsp;&nbsp;'
        footer = Template(foot_text)
        return(footer.substitute(links=link_string))
    
    def start_form(the_url, form_type="POST"):
        return('<form action="' + the_url + '" method="' + form_type + '">')
    
    def end_form(submit_msg="Submit"):
        return('<p></p><input type=submit value="' + submit_msg + '"></form>')
    
    def radio_button(rb_name, rb_value):
        return('<input type="radio" name="' + rb_name +
                                 '" value="' + rb_value + '"> ' + rb_value + '<br />')
    
    def u_list(items):
        u_string = '<ul>'
        for item in items:
            u_string += '<li>' + item + '</li>'
        u_string += '</ul>'
        return(u_string)
    
    def header(header_text, header_level=2):
        return('<h' + str(header_level) + '>' + header_text +
               '</h' + str(header_level) + '>')
    
    def para(para_text):
        return('<p>' + para_text + '</p>') 

    分析

    yate.py文件是放在cgi-bin文件下的,但是所使用的模版template是cgi-bin的父目录下,所以单独测试generate_list.py的时候,会出现找不到模版的情况,但是在web服务下通过点击timing data的链接时, generate_list.py却可以正常运行。

    我自作聪明地把 yate.py的open代码改成了
    with open(‘../templates/header.html’) as headf:
    这样测试generate_list.py的时候,没有IOError,能够找到templates下的模版,但是在服务器上,运行时,这段代码却有问题,找不到模版文件,暂时还不知道是什么原因,我对服务器执行cgi脚本的知识了解得还太少。

    后来找到的一个暂时的解决方案,是把yate.py里打开模版的路径换成绝对路径,这样generate_list.py单独测试时,能够正常生成html代码,而且在服务器上打开也能够正常执行。


    根据我自己的推断,在web上执行.py文件,虽然py文件在cgi-bin文件夹下,但是它的根目录应该是网站的根目录(cgi-bin的父目录),即这里的webapp文件夹,所以.py文件里编写是路径是“template/”,不需要返回上一级目录。athletes.pickle的生成的位置就是一个很好的证据。

    绝对路径的问题可以看看这个链接
    python 3.2之后把IOError 替换成了FileNotFoundError
    http://blog.csdn.net/yangting09032214/article/details/46785693

     
  • 相关阅读:
    树莓派4B 多屏 QT程序窗口全屏 QScreen 只能获取1个屏幕
    树莓派4B 微雪7寸触摸屏 双屏 触摸屏校正
    虚拟机 ubuntu18 树莓派4 QT5.14.2 交叉编译
    Qt 指定 so库 运行时路径
    building qtqml requires python
    python django 测试报告 发送邮件
    jmeter XPath Extractor
    python+unittest+HTMLTestRunner生成测试报告
    Genymotion、 uiautomatorviewer、 appium报错
    jmeter forEach控制器
  • 原文地址:https://www.cnblogs.com/jmmchina/p/6692230.html
Copyright © 2020-2023  润新知