from http.server import HTTPServer, CGIHTTPRequestHandler port = 8081 httpd = HTTPServer(('', port), CGIHTTPRequestHandler) print("Starting simple_httpd on port: " + str(httpd.server_port)) httpd.serve_forever()
二、index.htmlhtml
首頁;URL: 「http://localhost:8081/cgi-bin/book_list_view.py」 將調用 cgi-bin文件夾下的book_list_view.pypython
<html> <head> <title>BookStore</title> </head> <body> <h1>Welcome to My Book Store.</h1> <img src="resource/books.png"> <h3> please choose your favorite book, click <a href="cgi-bin/book_list_view.py">here</a>. </h3> <p> <strong> Enjoy!</strong> </p> </body> </html>
三、book_list_view.pynginx
圖書清單頁面。用戶選擇要查看的圖書,提交表單,而後調動圖書詳細界面。git
#Python標準庫中定義的CGI跟蹤模塊:cgibt import cgitb cgitb.enable() #啓用這個模塊時,會在web瀏覽器上顯示詳細的錯誤信息。enable()函數打開CGI跟蹤 #CGI腳本產生一個異常時,Python會將消息顯示在stderr(標準輸出)上。CGI機制會忽略這個輸出,由於它想要的只是CGI的標準輸出(stdout) import template.yate as yate import service.book_service as book_service #CGI標準指出,服務器端程序(CGI腳本)生成的任何輸出都將會由Web服務器捕獲,併發送到等待的web瀏覽器。具體來講,會捕獲發送到Stdout(標準輸出)的全部內容
#一個CGI腳本由2部分組成, 第一部分輸出 Response Headers, 第二部分輸出常規的html.
print("Content-type:text/html\n")#Response Headers #網頁內容:有html標籤組成的文本 print('<html>') print('<head>') print('<title>Book List</title>') print('</head>') print('<body>') print('<h2>Book List:</h2>') print(yate.start_form('book_detail_view.py')) book_dict=book_service.get_book_dict() for book_name in book_dict: print(yate.radio_button('bookname',book_dict[book_name].name)) print(yate.end_form('detail')) print(yate.link("/index.html",'Home')) print('</body>') print('</html>')
四、yate.pyweb
自定義的簡單模板,用於快捷生成html瀏覽器
def start_form(the_url, form_type="POST"): return('<form action="' + the_url + '" method="' + form_type + '">') def end_form(submit_msg="Submit"): return('<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>') def link(the_link,value): link_string = '<a href="' + the_link + '">' + value + '</a>' return(link_string)
五、book_detail_view.py服務器
圖書詳細頁面併發
import cgitb cgitb.enable() import cgi import template.yate as yate import service.book_service as book_service import template.yate as yate #使用cig.FieldStorage() 訪問web請求發送給web服務器的數據,這些數據爲一個Python字典 form_data = cgi.FieldStorage() print("Content-type:text/html\n") print('<html>') print('<head>') print('<title>Book List</title>') print('</head>') print('<body>') print(yate.header('Book Detail:')) try: book_name = form_data['bookname'].value book_dict=book_service.get_book_dict() book=book_dict[book_name] print(book.get_html) except KeyError as kerr: print(yate.para('please choose a book...')) print(yate.link("/index.html",'Home')) print(yate.link("/cgi-bin/book_list_view.py",'Book List')) print('</body>') print('</html>')
六、Book.py函數
圖書類測試
from template import yate class Book: def __init__(self,name,author,price): self.name=name self.author=author self.price=price @property def get_html(self): html_str='' html_str+=yate.header('BookName:',4)+yate.para(self.name) html_str+=yate.header('Author:',4)+yate.para(self.author) html_str+=yate.header('Price:',4)+yate.para(self.price) return(html_str)
七、book_service.py
圖書業務邏輯類
from model.Book import Book def get_book_dict(): book_dict={} try: with open('book.txt','r') as book_file: for each_line in book_file: book=parse(each_line) book_dict[book.name]=book except IOError as ioerr: print("IOErr:",ioerr) return(book_dict) def parse(book_info): (name,author,price)=book_info.split(';') book=Book(name,author,price) return(book)
八、book.txt
待顯示的圖書信息(書名;做者;價格)
The Linux Programming Interface: A Linux and UNIX System Prog;Michael Kerrisk;$123.01
HTML5 and CSS3, Illustrated Complete (Illustrated Series);Jonathan Meersman Sasha Vodnik;$32.23
Understanding the Linux Kernel;Daniel P. Bovet Marco Cesati;$45.88
Getting Real;Jason Fried, Heinemeier David Hansson, Matthew Linderman;$87.99