使用Python進行Web開發
- TCP/IP簡介
對于我們現在的通訊網絡實際上就是電腦之間多進程的通訊。TCP/IP囊括了互聯網的絕大部分協議,在網絡世界我們有對應的ID作為每個人的名字—IP地址,說白了就是我們的網絡接口,即我們的網卡。
IP協議與IP地址不是同一個概念。IP協議負責把數據從一臺計算機通過網絡發送到另一臺計算機。數據被分割成一小塊一小塊,然后通過IP包發送出去。由于互聯網鏈路復雜,兩臺計算機之間經常有多條線路,因此,路由器就負責決定如何把一個IP包轉發出去。IP包的特點是按塊發送,途徑多個路由,但不保證能到達,也不保證順序到達。
TCP協議則是建立在IP協議之上的。TCP協議負責在兩臺計算機之間建立可靠連接,保證數據包按順序到達。TCP協議會通過握手建立連接,然后,對每個IP包編號,確保對方按順序收到,如果包丟掉了,就自動重發。
Socket通常表示“打開了一個網絡連接”,實例化一個Socket對象則需要提供IP地址和端口號,再指定協議類型(TCP-- UCP—
- TCP編程
服務器端代碼Serve.py
import socket
import threading
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 0.0.0.0綁定到所有網絡地址 127.0.0.1本機地址,外部計算機無法訪問
s.bind(('127.0.0.1', 9999))
s.listen(5)
print('Waiting for connect..')
def tcplink(sock, addr):
print('Accept new connection %s:%s ' % addr)
#首先發送一個字符
sock.send(b'Welcome!')
while True:
# 接受來自客服端的數據
data = sock.recv(1024)
time.sleep(1)
# 如果接受為空,或者接收到退出指令,退出循環
if data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Conncetion from %s:%s close' % addr)
#寫一個循環讓服務器一直接受
while True:
# 接受新連接
sock, addr = s.accept()
# 創建新進程處理TCP連接
t = threading.Thread(target=tcplink,args=(sock, addr))
t.start()
s.send(b'exit')
客戶端代碼 client_local.py
# 導入socket庫
import socket
# 創建socket對象
# 其中AF_INET為Ipv4協議,AF_INET則為Ipv6,Sock_STREAM則是面向流的TCP協議
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 傳入tuple,創建連接
s.connect(('127.0.0.1', 9998))
# 發送請求數據
# GET請求數據 POST帶用戶數據 需要后加body,/為路徑 /為首頁 HTTP/1.1協議
# Host為域名 請求后連接關閉
# s.send(b'GET / HTTP/1.1\r\nHost:127.0.0.1\r\nConnection:close\r\n\r\n')
# 接受數據
print(s.recv(1024).decode('utf-8'))
for data in [b'Mick', b'Jack', b'Sarah']:
s.send(data)
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
遇到了兩個問題
OSError: [WinError 10038] 在一個非套接字上嘗試了一個操作。
再s.close()多了一個s.send(b’exit’),然而socket已經關閉無法進行發送
TypeError: not all arguments converted during string formatting,主要是因為addr返回的包括地址和端口組成的tuple需要使用兩個%s進行分配
最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。Apache、Nginx、Lighttpd等這些常見的靜態服務器就是干這件事情的。
我們用Python專注于生成HTML文檔。因為我們不希望接觸到TCP連接、HTTP原始請求和響應格式,所以,需要一個統一的接口,讓我們專心用Python編寫Web業務。
- WSGI接口 Web Server Gateway Interface
#WSGI.py
def application(environ, start_response):
#environ 包括HTTP請求消息的dict對象
#start_reponse 發送HTTP響應函數
start_response('200 OK', [('Content-Type', 'text/html')])
# 請求信息中的路由
route = environ['PATH_INFO']
return [b'<h1>Hello,web!</h1>']
#封裝好的服務器端
from wsgiref.simple_server import make_server
from WSGI import application
httpd = make_server('127.0.0.1',8000, application)
print('Serving HTTP on port 8000..')
httpd.serve_forever()
客戶端調用端口就可以訪問寫好的接口函數了
可以直接使用瀏覽訪問8000端口號
但是如果我們的服務器需要實現很多功能,不斷判斷路由和方法,會讓我們的代碼混亂,沒有辦法維護。我們需要在WSGI接口之上能進一步抽象,讓我們專注于用一個函數處理一個URL,至于URL到函數的映射,就交給Web框架來做。
pip install flask
# 或者
conda install flask
編寫代碼 app.py
from flask import Flask, request
app = Flask(__name__)
# 通過Flask裝飾器對象訪問路由以及方法
@app.route('/', methods=['GET','POST'])
def home():
return '<h1>Home</h1>'
@app.route('/signin', methods=['GET'])
def sigin_form():
return '''<form action="/signin" method="post">
<p><input name="username"></p>
<p><input name="password" type="password"></p>
<p><button type="submit">Sign In</button></p>
</form>'''
@app.route('/signin', methods=['POST'])
def sign():
# 從request中讀取表單內容
username = request.form['username']
if request.form['username'] == 'admin' and request.form['password'] == '123456':
return 'Welcome %s' % username
return '<h3>BAD passwd</h3>'
if __name__ == '__main__':
#不需要自己寫服務器
# Flask自帶服務器再5000是監聽
app.run()
處理URL的函數成為C:controller,檢查邏輯,用戶名是或否存在,去除用戶信息
視圖V:表示含有變量的HTML{{ name }}
模型M:{‘name’ : ‘Mick’ } =>一般由數據庫來充當這個角色
- 協程寫http服務器
import logging; logging.basicConfig(level=logging.INFO)
import asyncio, os, json, time
from datetime import datetime
from aiohttp import web
def index(request):
# 返回類型需要添加html
return web.Response(body=b'<h1>Awesome</h1>',content_type="text/html")
@asyncio.coroutine
def init(loop):
app = web.Application(loop=loop)
app.router.add_route('GET', '/', index)
srv = yield from loop.create_server(app.make_handler(), '127.0.0.1', 9000)
logging.info('server started at http://127.0.0.1:9000...')
return srv
loop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()
智能推薦
[Python] 使用Django開發Web框架
Django Web框架簡介 Django 項目是一個 python[1]定制框架,它源自一個在線新聞 Web 站點,于 2005 年以開源的形式被釋放出來。Django 框架的核心組件有: 用于創建模型的對象關系映射 為最終用戶設計的完美管理界面 一流的 URL 設計 設計者友好的模板語言 緩存系統。 Django符合MTV架構 Django的安裝 Django的安裝有兩種方法,具體可參考官網(...
使用Python開發Web爬蟲的筆記
1. python3使用urllib包(標準庫,不需要額外下載) urllib包中主要使用以下三大塊: request parse Error 同時加上BeautifulSoup4進行html的解析和內容提取 若使用顏色來判斷頁面中的正文,那么可能只會將紅色文本識別為正文,綠色文本則不會識別。 例如以下代碼: 2. 若將findAll的recursive的值設置為True,則該方法將會搜尋該節點下...
Windows下使用python-web3.py進行以太坊Dapp開發筆記--第2篇(以太坊公鑰加密功能python實現)
以太坊公鑰加密功能python實現 1.什么是公鑰、私鑰、地址 私鑰:32字節(256位),私鑰需要保管和隱蔽(非公開)(截取《以太坊技術詳解與實戰》) 公鑰:(由私鑰生成)64字節(512位),公鑰是公開的,不需要保密(截取《以太坊技術詳解與實戰》) 地址:20字節(160位),要注意,我們使用最多的地址并不等同于公鑰 地址的生成過程: 從私鑰得到一個512位(64字節)的公鑰之后,將公鑰進行s...
Java Web和Bootstrap進行web開發
獲取連接池的接口 獲取UUID的接口 c3p0-config.xml 這個文件可以直接放在src目錄下 BookDao常用代碼模板 FR:海濤高軟(QQ技術交流群:386476712)...
Python Web開發:測試驅動方法——從TDD基礎到使用Fabric進行自動部署【Windows用戶細節調整+bug解決】
記錄下TDD的各章執行bug以及在Windows環境下需要調整的細節。 目錄 第9章:Staging網站的部署測試 1. 【細節調整】通過更改測試臨時服務器運行的地址的參數以便使功能測試可以針對staging網站運行 2. 【細節調整】在本地創建requirements.txt文件然后通過GitHub傳到服務器 第10章:實現real網站的就緒部署 1. 【bug解決】讓Nginx服務靜態文件,重...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...