網(wǎng)絡(luò)
-
理論模型,分為七層
- 物理層
- 數(shù)據(jù)鏈路層
- 傳輸層
- 會話層
- 表示層
- 應(yīng)用層
-
實際應(yīng)用,分為四層
- 鏈路層
- 網(wǎng)絡(luò)層
- 傳輸層
- 應(yīng)用層
-
IP地址
-
IPV4 地址族,4個字段組成,每個字段取值0-255
局域網(wǎng)IP,
192.168.XXX,XXX本機本地地址,
127.0.0.1
IPV6 地址族,8個字段組成,每個字段取值0000-FFFF
-
-
端口
設(shè)備上每個應(yīng)用需要與外界通信的地址
范圍是 0-65535
知名端口 0-1023
非知名端口 1024-65535
-
套接字
我理解的套接字相當于與電話,而人則代表每個設(shè)備;當兩個人需要通信時,需要電話.這就是套接字,而知道電話是不夠的,還需要知道電話號碼,這樣才能確保電話打到你想通話的哪個人去
套接字對象由addr(host,port)地址定義,host是IP地址,port代表端口
host主要用來確定是IP地址為哪一個的電腦
port主要用來確定是該電腦上的哪個軟件
-
域名
網(wǎng)絡(luò)上計算名,或計算機組的名稱
-
瀏覽器根據(jù)域名來查找對應(yīng)的IP地址
查找本地hsot文件,檢查是否有對應(yīng)的IP地址
如果沒有,查找本地DNS服務(wù)器.也就是運營商,檢查是否有對應(yīng)的IP
如果沒有,本地DNS服務(wù)器查找根DNS服務(wù)器,檢查是否有對應(yīng)的IP
如果沒有,根DNS服務(wù)器返回消息給本地DNS服務(wù)器,讓其到域服務(wù)器查找IP
-
DNS 域名服務(wù)器系統(tǒng)
DNS將域名映射到對應(yīng)的IP地址
-
DNS查詢
- 遞歸查詢
image- 迭代查詢
image -
DNS 負載均衡
- 在DNS服務(wù)器中,為域名配置多個IP地址,根據(jù)距離遠近,使用距離較近的IP
socket 庫
-
協(xié)議家族
-
基于文件
- AF_UNIX 同臺機器進程之間的通行
-
基于網(wǎng)絡(luò)
AF__INET IPV4協(xié)議
AF_INET6 IPV6協(xié)議
-
-
網(wǎng)絡(luò)協(xié)議
SOCK_STREAMTCP協(xié)議 , 連接的套接字,只有當服務(wù)器與客戶端連接后,才開始傳輸數(shù)據(jù),可以確定數(shù)據(jù)的先后,也可以確定對方一定能接收到消息SOCK_DGRAMUDP協(xié)議 , 無連接的套接字,服務(wù)器不斷的監(jiān)聽某個套接字,從這個套接字獲取或者發(fā)送數(shù)據(jù),無法確定數(shù)據(jù)的先后順序,也無法確定對方是否收到消息
-
直接調(diào)用的函數(shù)
getfqdn(name)返回name的域名gethostbyname(hostname)返回主機名的IPV4地址gethostname()返回正在執(zhí)行當前解釋器的機器的主機名sethostname(name)將本機主機名設(shè)置為name
-
socket(family,type)套接字對象類-
函數(shù)
-
通用函數(shù)
bind(addr)服務(wù)器綁定套接字,addr為(host,port)shuntdown()關(guān)閉連接setblocking(boolean)設(shè)置是否為阻塞模式-
settimeout(second)設(shè)置超時時間-
None阻塞模式 -
0非阻塞模式 -
非0值在規(guī)定時間后拋出異常
-
close()關(guān)閉套接字
-
TCP 函數(shù)
listen()監(jiān)聽地址,阻塞式的,不斷循環(huán)監(jiān)聽地址accept()服務(wù)器接收TCP客戶端連接,返回新的連接的套接字和客戶端的地址send(data)發(fā)送數(shù)據(jù)sendall(data)發(fā)送所有數(shù)據(jù)-
recv(bufsize)接收TCP指定字節(jié)數(shù)的數(shù)據(jù),一旦超過指定字節(jié),就需要使用循環(huán)接收的方式接收完整的數(shù)據(jù)短鏈接法,發(fā)送數(shù)據(jù)完畢后關(guān)閉連接,讓
recv()函數(shù)獲取連接關(guān)閉后自動取消阻塞模式末尾標志法,在末尾添加相應(yīng)哨兵值,在
recv()函數(shù)接收到哨兵值之后跳出接收數(shù)據(jù)的死循環(huán),進行下一步操作負載長度法,提前告知長度,后根據(jù)長度判斷是否跳出接收數(shù)據(jù)的死循環(huán)
connect(addr) 發(fā)起連接,向addr(host,port)發(fā)起連接
# 設(shè)置TCP服務(wù)器 import socket,time server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('127.0.0.1',12345)) server.listen() con,addr = server.accept() data = con.recv(1024) text = data.decode() print(text) data = '{0} : {1}'.format(time.ctime(),text).encode() con.sendall(data) con.close() server.close() # 設(shè)置TCP客戶端 import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',12345)) text = 'Hello' client.sendall(text.encode()) data = client.recv(1024) print(data.decode()) client.close() -
UDP 函數(shù)
recvfrom(bufsize)接收UDP消息,返回連接的套接字地址sendto(data,addr)將data數(shù)據(jù)發(fā)送到指定addr地址
# 設(shè)置UDP服務(wù)器 import socket,time server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) server.bind(('127.0.0.1',12345)) data,addr = server.recvfrom(1024) text = data.decode() print(text) server.sendto('{0} : {1}'.format(time.ctime(),text).encode(),addr) server.close() # 設(shè)置UDP客戶端 import socket client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) text = 'Hello' client.sendto(text.encode(),('127.0.0.1',12345)) data,addr = client.recvfrom(1024) print(data.decode())
-
-
socketserver 網(wǎng)絡(luò)服務(wù)器框架模塊
此模塊提供網(wǎng)絡(luò)服務(wù)器框架,可以使開發(fā)者更加快捷的開發(fā)出相應(yīng)的網(wǎng)絡(luò)服務(wù)器
-
服務(wù)器server對象
-
BaseServer(server_address,RequestHandlerClass)所有Server對象的超類,同步處理請求,只有當一個請求處理完成之后才能處理下一個請求,每次只能完成一個請求RequestHandlerClass處理請求類get_request()接收客戶端請求,并返回一個和客戶端連接的套接字和客戶端地址組成的元組server_bind(addr)綁定地址serve_forever()永遠處理請求shutdown()停止處理請求server_close()關(guān)閉服務(wù)器
TCPServer (server_address,RequestHandlerClass)繼承于BaseServer,完善了TCP的相關(guān)方法,用于TCP服務(wù)器的創(chuàng)建,需要重寫RequestHandlerClass
# 改寫的上面采用socket庫編寫的TCP服務(wù)器 import socketserver,time class Server(socketserver.TCPServer): pass class MyRequestHandler(socketserver.StreamRequestHandler): def handle(self): data = self.request.recv(1024) text = data.decode() print(text) data = '{0} : {1}'.format(time.ctime(),text).encode() self.request.sendall(data) server = Server(('127.0.0.1',12345),MyRequestHandler) server.serve_forever() # 客戶端 import socket with socket.socket(socket.AF_INET,socket.SOCK_STREAM)as client: client.connect(('127.0.0.1',12345)) client.sendall('hello'.encode()) data = client.recv(1024) print(data.decode())-
UDPServer (server_address,RequestHandlerClass)繼承于BaseServer,完善了TCP的相關(guān)方法,用于UDP服務(wù)器的創(chuàng)建,需要重寫RequestHandlerClass
# 服務(wù)器端 import socketserver,time class Server(socketserver.UDPServer): pass class MyRequestHandler(socketserver.DatagramRequestHandler): def handle(self): data,con = self.request print(data.decode()) data = '{0} : {1}'.format(time.ctime(),data.decode()).encode() con.sendto(data,self.client_address) server = Server(('127.0.0.1',12345),MyRequestHandler) server.serve_forever() # 客戶端 import socket with socket.socket(socket.AF_INET,socket.SOCK_DGRAM)as client: data = 'hello'.encode() client.sendto(data,('127.0.0.1',12345)) data = client.recv(1024) print(data.decode())-
適用于Unix平臺的服務(wù)器,
UnixStreamServer (server_address,RequestHandlerClass)UnixDatagramServer (server_address,RequestHandlerClass)
image -
-
擴展功能的Mixin類
ForkingMixIn多進程MIXIN類 ,可以與其他Server對象進行組合,適用于Linux 平臺ThreadingMixIn多線程MIXIN類,可以與其他Server對象進行組合
-
模塊中已組合的擴展功能的服務(wù)器Server類
ForkingTCPServer(server_address,RequestHandlerClass)多進程TCP服務(wù)器類,ForkingMixIn與TCPServer的組合ForkingUDPServer(server_address,RequestHandlerClass)多進程UDP服務(wù)器類,ForkingMixIn與UDPServer的組合ThreadingTCPServer(server_address,RequestHandlerClass)多線程TCP服務(wù)器類,ThreadingMixIn與TCPServer的組合ThreadingUDPServer(server_address,RequestHandlerClass)多線程UDP服務(wù)器類,ThreadingMixIn與UDPServer的組合
-
請求處理類
-
BaseRequestHandler處理請求類,其中定義了三個方法:setup、handle、finish,都默認什么都不做,需要進行重寫才能使用,是其他處理請求類的超類setup()在handle方法之前調(diào)用的操作-
handle()處理客戶端請求的方法-
self.request在不同Server服務(wù)器對象中具有不同的含義在TCPServer中,返回的是連接的客戶端的套接字
在UDPServer中,返回的數(shù)據(jù)和連接的客戶端套接字的一個元組
self.client_address返回連接的客戶端的地址self.rfile可以從此屬性中讀取客戶端發(fā)送的數(shù)據(jù)self.wfile可以從此屬性中寫入服務(wù)器發(fā)給客戶端的數(shù)據(jù)
-
finish()在handle方法之后調(diào)用的操作
StreamRequestHandlerTCP處理請求類,是BaseRequestHandler的子類,實現(xiàn)了關(guān)于TCP的相關(guān)方法,但需要實現(xiàn)handle方法DatagramRequestHandlerUDP處理請求類,是BaseRequestHandler的子類,實現(xiàn)了關(guān)于UDP的相關(guān)方法,但需要實現(xiàn)handle方法
-
ftplib 模塊
FTP (FileTransferProtocal) 文件傳輸協(xié)議
-
用戶
Real賬戶 注冊賬戶
Guest賬戶 臨時賬戶
Anonymous 匿名賬戶
-
端口
21端口為控制和命令端口20端口為數(shù)據(jù)端口
-
FTP(host,usr,passwd)類
可以使用上下文管理協(xié)議 即
with語句connect(host,port)當沒有在實例化FTP定義host時,則需要調(diào)用connect函數(shù)指定host和portlogin(usr,passwd)給定賬號密碼登錄,默認usr為anonymous,密碼為anonymous@abort()中斷傳輸?shù)奈募?/p>sendcmd(cmd)向服務(wù)器發(fā)送字符串命令,并返回響應(yīng)代碼retrbinary(cmd,callback)以二進制形式接收文件,callback為用于接收文件的回調(diào)函數(shù)storbinary(cmd,fp)以二進制形式上傳文件,fp為二進制流retrlines(cmd,callback)文本形式接收文件storlines(cmd,fp)文本形式上傳文件nlst()返回文件名列表dir()輸出文件名列表到sys.stdoutrename(old,new)重命名delete(filename)刪除文件pwd()返回當前目錄路徑cwd(path)將path設(shè)置為當前路徑mkd(path)創(chuàng)建新目錄rmd(dirname)刪除dirname目錄size(file)返回文件大小quit()關(guān)閉連接
import ftplib
#定義回調(diào)函數(shù),將retrbinary函數(shù)接收到的數(shù)據(jù)寫入本地文件中
def file(data):
with open(r'1.txt','wb')as f:
f.write(data)
# 指定FTP的host,獲得套接字連接
con = ftplib.FTP('ftp.acc.umu.se')
# 連接FTP服務(wù)器
con.connect()
# 匿名賬戶登錄
con.login()
con.dir()
# 下載文件,并調(diào)用file函數(shù),將數(shù)據(jù)寫入本地文件
con.retrbinary('RETR robots.txt',file)
# 關(guān)閉連接
con.close()
email 電子郵件模塊
-
郵件傳輸模式
MUA 客戶端程序
MTA (Mail Transfer Agent) 郵件傳輸代理,將發(fā)件人的郵件傳輸?shù)桨l(fā)件人郵箱所在的服務(wù)器
MDA (Mail Delivery Agent) 郵件投遞代理,發(fā)件人郵箱所在的服務(wù)器將郵件傳輸?shù)绞占肃]箱所在的服務(wù)器
MRA (Mail retrieva Agent) 郵件獲取代理,收件人郵箱所在的服務(wù)器將郵件獲取到收件人的郵箱地址中去
image -
郵件傳輸使用MIME協(xié)議(多用途互聯(lián)網(wǎng)郵件擴展),即電子郵件需要符合相應(yīng)的MIME格式,才能進行發(fā)送
MIME協(xié)議中包括郵件標頭、郵件消息體兩個部分
郵件標頭是key-value形式的字符串,每個標頭獨占一行
-
標頭屬性
-
From發(fā)件人地址 -
To收件人地址 -
Cc抄送地址 -
Subject主題 -
Content-Type郵件體中包含的內(nèi)容類型 -
Content-Disposition: "attachment;filename='name.type'"設(shè)置附件的下載方式和顯示名稱,其中attachment為附件方式打開,inline在郵件中打開
-
標頭后跟著空行,下面為郵件消息體
消息體為郵件的具體內(nèi)容
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
From: mine<xxxx@163.com>
To: you<xxx@qq.com>
Subject: =?utf-8?b?6YKu5Lu25qCH6aKY?=
6L+Z5piv5LiA5Lu95paH5pys5raI5oGv6YKu5Lu2
-
mime構(gòu)造郵件消息模塊每個MIME類型的郵件消息對象只需要添加標頭就可以作為郵件進行發(fā)送
multipart.MIMEMultipart(subtype ='mixed',boundary = None,spartparts = None,policy = compat32)構(gòu)造多個消息組成的總消息application.MIMEApplication(data,subtype = '八位字節(jié)流',encoder = email.encoders.encode_base64)構(gòu)造MIME郵件的Application消息audio.MIMEAudio(audiodata,subtype = None,encoder = email.encoders.encode_base64)構(gòu)造MIME郵件的Audio消息image.MIMEImage(imagedata,subtype = None,encoder = email.encoders.encode_base64)構(gòu)造MIME郵件的Image消息text.MIMEText(text,subtype ='plain',charset = None,*,policy = compat32)構(gòu)造一個MIME郵件的文本消息
-
message郵件消息操作模塊-
EmailMessage類- 同下
-
Message類as_string()將消息對象作為字符串返回as_bytes()將消息對象作為二進制流返回attach(message)將message消息對象添加到當前消息對象items()返回消息字段標題和值的元組的列表add_header(name,value)添加郵件標頭
get_payload(i=None, decode=False)返回郵件消息中每行內(nèi)容所組成的列表,選擇是否解碼,一般需要填入Truewalk()迭代器,迭代郵件消息的每一行
-
-
header構(gòu)造郵件標頭模塊Header(str=None,charset=None,header_name = NONE)類 創(chuàng)建符合MIME協(xié)議的標頭-
郵件標頭可以通過兩種方式進行構(gòu)造
- 使用Header類進行構(gòu)造,使用消息對象的屬性進行賦值
msg['From'] = Header('xxxx@xx.com')-
add_header(name,value)函數(shù),使用消息對象的函數(shù)進行賦值
msg.add_header('From','xxxx@xx.com') -
郵件頭的解碼
-
decode_header(_header)解碼標頭值,返回(decode_string,charset)組成的元組的列表
-
-
parse 郵件解碼模塊
-
BytesParser二進制數(shù)據(jù)解析類parse(fp,headersonly = False )解析二進制流,生成消息對象parsebytes(bytes,headersonly = False )解析二進制數(shù)據(jù),生成消息對象BytesHeaderParser()解析標頭二進制數(shù)據(jù),返回標頭對象
-
Parser文本解析類parse(fp,headersonly = False )解析文本流,生成消息對象parsestr(text,headersonly = False )解析字符串,生成消息對象HeaderParser()解析標頭文本數(shù)據(jù),返回標頭對象
-
-
email模塊下直接使用的解析類
message_from_bytes(s,_class = None,*,policy = policy.compat32 )從二進制數(shù)據(jù)返回消息對象message_from_binary_file(fp,_class = None,*,policy = policy.compat32 )從二進制流返回消息對象message_from_string(s,_class = None,*,policy = policy.compat32 )從字符串返回消息對象message_from_file(fp,_class = None,*,policy = policy.compat32 )從文本流中返回消息對象
smtplib SMTP簡單郵件發(fā)送協(xié)議模塊
SMTP 是負責(zé)郵件發(fā)送的協(xié)議
-
SMTP(host,port)未加密的SMTP類可以使用上下文管理協(xié)議,即
with語句connect(host,port)連接到郵件服務(wù)器login(usr,pwd)登錄sendmail(from_addr,to_addr,msg)發(fā)送郵件 msg為字符串,也就是需要通過消息對象調(diào)用as_string()方法quit()關(guān)閉連接
-
SMTP_SSL(host,port)ssl加密的SMTP類- 方法同上
-
發(fā)送一封純文本格式的郵件
import smtplib from email.mime.text import MIMEText usr = 'xxx@163.com' pwd = 'xxxxx' to_mail = 'xxxxx@qq.com' # 構(gòu)造文本消息郵件 msg = MIMEText('這是一份文本消息郵件') # 添加標頭,使之變?yōu)猷]件 msg['From'] = 'mine<{0}>'.format(usr) msg['To'] ='you<{0}>'.format(to_mail) msg['Subject'] = '郵件標題' # 發(fā)送郵件 with smtplib.SMTP()as con: # 變?yōu)閐ebug模式,輸出信息到控制臺 con.set_debuglevel(1) # 連接郵件服務(wù)器 con.connect('smtp.163.com',25) # 登錄 con.login(usr,pwd) # 發(fā)送郵件 con.sendmail(usr,to_mail,msg.as_string()) -
發(fā)送一封html格式的郵件
import smtplib from email.mime.text import MIMEText usr = 'xxx@163.com' pwd = 'xxxxx' to_mail = 'xxxxx@qq.com' # 構(gòu)造html content ="<html><h1>這是一封html郵件</h1></html>" # 構(gòu)造文本消息郵件 msg = MIMEText(content,'html','utf-8') # 添加標頭,使之變?yōu)猷]件 msg['From'] = 'mine<{0}>'.format(usr) msg['To'] ='you<{0}>'.format(to_mail) msg['Subject'] = '郵件標題' # 發(fā)送郵件 with smtplib.SMTP()as con: # 變?yōu)閐ebug模式,輸出信息到控制臺 con.set_debuglevel(1) # 連接郵件服務(wù)器 con.connect('smtp.163.com', 25) # 登錄 con.login(usr, pwd) # 發(fā)送郵件 con.sendmail(usr, to_mail, msg.as_string()) -
發(fā)送一封帶有附件的郵件
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from email.mime.text import MIMEText usr = 'xxx@163.com' pwd = 'xxxxx' to_mail = 'xxxxx@qq.com' file = r'C:\Users\wudiz\Desktop\BaseServer.png' # 構(gòu)造文本消息郵件 msg = MIMEMultipart('組合郵件') # 添加標頭,使之變?yōu)猷]件 msg['From'] = 'mine<{0}>'.format(usr) msg['To'] ='you<{0}>'.format(to_mail) msg['Subject'] = '郵件標題' # 構(gòu)造文本 text = MIMEText('這是一封組合郵件') # 添加到msg組合消息對象中 msg.attach(text) # 構(gòu)造附件 data = MIMEApplication(open(file,'rb').read()) # 添加MIME類型 data.add_header('Content-Type','application/octet-stream') # 設(shè)置附件 data.add_header('Content-Disposition',"attachment;filename='1.png'") # 添加到msg組合消息對象中 msg.attach(data) # 發(fā)送郵件 with smtplib.SMTP()as con: # 變?yōu)閐ebug模式,輸出信息到控制臺 con.set_debuglevel(1) # 連接郵件服務(wù)器 con.connect('smtp.163.com', 25) # 登錄 con.login(usr, pwd) # 發(fā)送郵件 con.sendmail(usr, to_mail, msg.as_string())
poplib 郵局協(xié)議模塊
POP3 (Post Office Protocol - Version 3) 郵局協(xié)議版本3
-
POP3(host,port)非加密POP3協(xié)議類set_debuglevel(1)設(shè)置為調(diào)試模式stls()以tls驗證服務(wù)器getwelcome()返回服務(wù)器的問候語字符串capa()查詢服務(wù)器的功能user(usr)發(fā)送用戶名pass_(pwd)發(fā)送密碼apop(usr,pwd)使用APOP身份驗證登錄郵箱rpop(usr,pwd)使用RPOP身份驗證登錄郵箱stat()獲取郵箱狀態(tài),返回(message_count,mailbox_size)的元組list(num)獲取郵件列表,如果設(shè)置了數(shù)字,則為數(shù)字所在編號郵件的內(nèi)容,返回(response,num,octets)組成的元組 response為響應(yīng)代碼,num為郵件數(shù)量,octets為郵件大小retr(num)檢索郵件號,返回(response,lines,octets)組成的元組 lines為郵件每行組成的一個二進制列表,需要將其每個一行的組合起來才能變成二進制郵件,二進制郵件解碼才能變?yōu)猷]件dele(num)標記郵件號,退出登錄后刪除rset()立即刪除標記的郵件號quit()關(guān)閉連接
-
POP3_SSL(host,port)SSL加密POP3協(xié)議類- 方法同上,現(xiàn)在一般使用該類
import poplib import email.header # 指定連接POP3服務(wù)器的host和port con = poplib.POP3('pop3.163.com',110) con.set_debuglevel(1) con.user('xxx') con.pass_('xxx') print(con.getwelcome()) # 選定郵箱中的第三封郵件 list = con.retr(3) # 設(shè)置二進制對象 data = b'' # 將二進制郵件的每一行寫入data中,構(gòu)建完整的郵件,按每行進行寫入 for i in list[1]: data = data + i + b'\r\n' con.quit() # 解析為MIME消息對象 mail = email.message_from_bytes(data) # 解析標頭中的標題 subject = email.header.decode_header(mail.get('Subject')) # 解碼Subject標頭值的字符串,并打印 print(subject[0][0].decode(subject[0][1])) # 按base64解碼消息中的內(nèi)容 content = mail.get_payload(decode=True) # 按UTF-8解碼內(nèi)容 print(content.decode())
http 超文本傳輸協(xié)議模塊
-
http協(xié)議 是Hyper Text Transfer Protocol的縮寫,簡稱為超文本傳輸協(xié)議
HTTP 的默認端口為80
HTTPS的默認端口為443
永遠是客戶端先發(fā)起請求,然后服務(wù)器響應(yīng)請求
-
工作模式
-
建立連接
- 需要進行三次握手
- 客戶端發(fā)送一個請求給服務(wù)端要求建立連接,進入等待狀態(tài)(SYN_SEND)
- 服務(wù)端同意連接,發(fā)送一個響應(yīng)給客戶端,進入等待狀態(tài)(SYN_SEND)
- 客戶端接收這個響應(yīng),并與之建立連接(ESTABLISHED)
- 需要進行三次握手
接收數(shù)據(jù)
結(jié)束連接
-
-
請求報文
Request[圖片上傳失敗...(image-49e11e-1536041654038)]
-
請求行包括了請求方法,請求的url和http版本
-
請求方法
POST向服務(wù)器提交數(shù)據(jù) 改GET請求數(shù)據(jù) 查PUT向服務(wù)器上傳數(shù)據(jù) 增DELETE請求服務(wù)器刪除相應(yīng)數(shù)據(jù) 刪
-
-
請求頭是key-value形式的,其中有以下屬性
-
Host請求資源的主機地址(必須存在) -
User-Agent客戶端的瀏覽器類型和版本 -
Accept-Language客戶端申明自己接收的語言 -
Accept客戶端申明自己想要接收數(shù)據(jù)的類型- gzip
- deflate
-
Accept-Encoding客戶端申明自己接收的編碼,通常指定壓縮方法 -
Cookie發(fā)送cookie值 -
Connection連接方式-
keep-alive持久連接,當訪問網(wǎng)頁后連接不會關(guān)閉 -
close短連接,訪問后就關(guān)閉,下次建立新的連接
-
-
Keep-Alive保持連接的時間 -
Referer表示用戶從該網(wǎng)頁訪問服務(wù)器 -
Date此報文產(chǎn)生的日期 -
Authorization客戶端權(quán)限
-
空行,請求頭和請求體之間必須有一個空行
請求體
-
-
響應(yīng)報文
Response[圖片上傳失敗...(image-8a1169-1536041654038)]
-
響應(yīng)行,包括了服務(wù)器軟件的版本號,返回的狀態(tài)碼和相應(yīng)短語
- 1XX 服務(wù)器已接收請求,繼續(xù)處理
- 2XX 服務(wù)器請求已被處理
- 3XX 重定向
- 4XX 客戶端錯誤
- 5XX 服務(wù)器錯誤
-
響應(yīng)頭
-
Location重定向到另一個位置 -
Server服務(wù)器軟件 -
Date此報文產(chǎn)生的日期 -
Content-Length響應(yīng)體的長度 -
Content-Type聲明發(fā)送響應(yīng)體的類型和編碼
-
空行
響應(yīng)體,也就是服務(wù)器返回的請求資源
-
-
clientHTTP客戶端模塊模塊-
HTTPConnection(host,port = None)使用http協(xié)議連接服務(wù)器,返回一個HTTPConnection對象request(method,url,body = None,headers = {})向服務(wù)器發(fā)送請求getresponse()返回服務(wù)器相應(yīng)set_debuglevel(1)設(shè)置調(diào)試,將輸出打印到控制臺close()關(guān)閉連接
-
HTTPSConnection(host,port = None)使用https協(xié)議簡介服務(wù)器,返回一個HTTPSConnection對象- 同上
-
HTTPResponse對象read()讀取響應(yīng)內(nèi)容getheaders()返回(屬性,值)組成的元組列表getheader(name)返回屬性為name的值version返回協(xié)議版本status返回狀態(tài)碼
from http.client import * con = HTTPConnection('www.baidu.com') con.set_debuglevel(1) con.request('GET','http://www.baidu.com') response = con.getresponse() print(response.read()) response.close() con.close() -
-
serverHTTP服務(wù)器模塊-
服務(wù)器框架,此模塊繼承于socketserver.TCPServer
HTTPServer(server_address,RequestHandlerClass )ThreadingHTTPServer(server_address,RequestHandlerClass )
-
處理HTTP請求類
-
BaseHTTPRequestHandler(request,client_address,server )處理http請求的基本類command請求形式path請求的urlrequest_version請求的http版本headers請求報文的標頭rfile讀取流wfile寫入流-
protocol_version設(shè)置http版本協(xié)議默認為HTTP/1.0 短連接
HTTP/1.1 持久連接
send_response(code, message=None)將響應(yīng)狀態(tài)碼添加到緩沖區(qū)send_header(keyword, value)將響應(yīng)頭添加到緩沖區(qū)end_headers()發(fā)送空行version_string()返回服務(wù)器軟件的版本號date_time_string()返回當前時間address_string()返回呼叫的客戶端地址
# 使用BaseHTTPRequestHandler創(chuàng)建HTTP服務(wù)器 from http.server import * html = ''' <html> <head> <title>Server</title> </head> <body> hello Python! </body> </html> ''' class myhttpserver(HTTPServer): pass class myhttphandler(BaseHTTPRequestHandler): def do_GET(self): url = self.path print(url) self.send_response(200) self.send_header('Hello','from server s welcome') self.end_headers() self.wfile.write(html.encode()) server = myhttpserver(('127.0.0.1',8888),myhttphandler) server.serve_forever() # 現(xiàn)在使用http://127.0.0.1:8888/打開網(wǎng)站吧-
SimpleHTTPRequestHandler(request,client_address,server,directory = None )普通HTTP請求處理類-
除了和
BaseHTTPRequestHandler函數(shù)一致時,還另外定義了directory屬性,do_HEAD(),do_GET()方法directory屬性: 如果未指定,則代表提供的文件的目錄是當前目錄do_HEAD()默認給定Server, Date, Connection, Content-Type, Content-Length, Last-Modified的標頭do_GET()如果代碼所在位置有index.html,則會發(fā)送這個網(wǎng)頁給客戶端,否則將建立一個基于當前目錄的類似于FTP的服務(wù)器
-
-
# 類似于FTP服務(wù)器 from http.server import * class myhttpserver(HTTPServer): pass class myhttphandler(SimpleHTTPRequestHandler): pass server = myhttpserver(('127.0.0.1',8888),myhttphandler) server.serve_forever() # 使用index.html # 在代碼所在目錄編寫index.html文件 ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My Page</title> </head> <body> <h1>Hello Python3!</h1> </body> </html> ''' # 再次運行服務(wù)器,使用瀏覽器訪問,即可以查看結(jié)果-
CGIHTTPRequestHandler(request,client_address,server )調(diào)用CGI程序處理請求修改了
SimpleHTTPRequestHandler定義的do_GET和do_HEAD方法,更改為使用CGI程序輸出的方法 如果沒有CGI程序,就會像SimpleHTTPRequestHandler一樣,建立一個類似于FTP的服務(wù)器cgi_directories包含CGI程序的目錄,默認為當前目錄下的['/cgi-bin', '/htbin']do_POST()定義了POST方法,允許客戶端發(fā)送信息到服務(wù)器得CGI程序中,如果POST到非CGI程序上,會提示501錯誤
# 先定義一個能POST請求的html頁面,命名為index.html ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>請輸入文字</h1> <form action="http://127.0.0.1:8888/cgi-bin/cc.py" method="post" id="myform"> <p><input type="text" name="text"></p> </form> <button type="submit" form="myform">發(fā)送</button> </body> </html> ''' # CGI服務(wù)器 from http.server import * class myhttpserver(HTTPServer): pass class myhttphandler(CGIHTTPRequestHandler): pass server = myhttpserver(('127.0.0.1',8888),myhttphandler) server.serve_forever() # 編寫CGI程序,放入cgi-bin目錄下 import cgi import cgitb cgitb.enable() html = ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>你提交的是:</h1> <h2>{0}</h2> </body> </html> '''.format(cgi.FieldStorage().getfirst('text')) print(html) # 運行程序,會輸出你在頁面上輸入的信息 -
-
cookies HTTP狀態(tài)管理,主要用于服務(wù)器端創(chuàng)建cookie
-
Netscape形式的cookie :
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE- NAME為該cookie的名稱,為必填選項
- Expires為該cookie的終止日期 形式為
星期幾,DD-MM-YY HH:MM:SS GMT,GMT表示格林尼治時間,如不填該cookie不會保存在硬盤中,該cookie隨著瀏覽器的關(guān)閉消失 - Domain為該cookie的作用域,如果不填,則為該服務(wù)器的域名
- Path為該服務(wù)器下那些頁面可以獲取該cookie,填'/'為該服務(wù)器下所有頁面
- 加密協(xié)議,當前只有一種,即HTTPS
-
RFC2109中定義的cookie :
Set-Cookie: Name = Value; Comment = value; Domain = value; Max-Age = value; Path = Value;Secure; Version = 1 * DIGIT;- NAME必須為一個JSESSIONID,必填
- Domain為該cookie的作用域,必須以
.開始 - Max-Age為該cookie的生存時間,以秒為單位
- Secure必填
-
BaseCookie(input) 類
該類用于創(chuàng)建cookie,是一個類似于字典的對象,每向其中添加一個key,value值就會創(chuàng)建一個
Set-Cookie: key:value的響應(yīng)頭信息,其中key必須是一個字符串,value是一個Morsel對象,可以向其中添加其他頭信息操作-
定義的方法:
-
value_decode(val )待續(xù) -
value_encode(val )待續(xù) -
output(attrs = None,header ='Set-Cookie:',sep ='\ r \ n' )將cookie對象作為符合html標準的字符串輸出 -
load(rawdata )將接收到的字符串對象解析為cookie
-
-
SimpleCookie(input) 類
- BaseCookie的子類,重寫實現(xiàn)了value_decode,value_encode方法
-
Morsel 類
-
常用常量
- expires
- path
- comment
- domain
- max-age
- secure
- version
- httponly
-
常用方法
-
set(key,value,coded_value )添加key,設(shè)置value值 -
output(attrs = None,header ='Set-Cookie:' )作為html形式輸出 -
update(dict)將字典中的key和value添加到對象中
-
-
-
# 創(chuàng)建一個cookie,使用了幾種不同的方式
from http.cookies import *
cookie = SimpleCookie()
cookie["name"] = "mycookie"
dict = {'path':'/','comment':'這是cookie'}
cookie['name'].update(dict)
cookie['name']['domain'] = '127.0.0.1'
cookie['whatever'] = 'i dont know'
print(cookie)
-
cookiejar 持久化的cookie操作模塊,主要用于客戶端的操作,如爬蟲
具體應(yīng)用在urllib模塊中
-
CookieJar 類,該類用來操作儲存在內(nèi)存中的cookie
MozillaCookieJar(filename,delayload = None,policy = None )類 可以從加載和保存的Cookie到磁盤Mozilla的cookies.txtLWPCookieJar(filename,delayload = None,policy = None )類 可以從加載和cookie保存到磁盤與的libwww-perl的庫的兼容格式Set-Cookie3的文件格式add_cookie_header(requst)向request對象中添加一個cookie對象extract_cookies(response,request)從http的response中提取cookie并儲存在cookieJar對象中make_cookies(response,request)從http的response中提取cookieset_cookie(cookie)向cookieJar添加cookie對象clear(keys)清除名為key的cookie參數(shù)
# 獲取cookie from urllib.request import * from http.cookiejar import * url = 'http://www.baidu.com' headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36' } request = Request(url=url, headers=headers) response = urlopen(request) cookie = CookieJar() cookie.extract_cookies(response,request) print(cookie) -
FileCookieJar 類,該類主要用于操作已經(jīng)持久到文件中的cookie
具有以上CookieJar的所有函數(shù)之外,額外添加了以下函數(shù)
filename默認保存cookie的文件save(filename = None,ignore_discard = False,ignore_expires = False )將cookie保存在文件中,方法未實現(xiàn),但是在CookieJar的子類LWPCookieJar,MozillaCookieJar實現(xiàn)了其方法load(filename = None,ignore_discard = False,ignore_expires = False )從文件中加載cookierevert(filename = None,ignore_discard = False,ignore_expires = False )清除所有cookie,并從文件中重新加載cookie
# 以LWPCookieJar為例,將cookie保存到文件中 from urllib.request import * from http.cookiejar import LWPCookieJar url = 'http://www.baidu.com' headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36' } request = Request(url=url, headers=headers) response = urlopen(request) filecookie = LWPCookieJar() filecookie.extract_cookies(response,request) filecookie.save(r'a.txt')
cgi 通用網(wǎng)關(guān)接口支持模塊、cgitb CGI腳本的回溯管理器模塊
cgitb用于調(diào)試cgi腳本程序
- enable() 將錯誤信息輸出到訪問的html頁面
cgi是服務(wù)器運行時調(diào)用的外部程序,通過通用CGI接口與服務(wù)器通信,默認放在['/cgi-bin', '/htbin']目錄下
-
通常由兩個部分組成
- 第一部分為響應(yīng)頭,用于告知客戶端傳輸數(shù)據(jù)的類型,后面跟空行,用于將響應(yīng)體分開
print("Content-Type: text/html") print()- 第二部分為響應(yīng)的數(shù)據(jù)
-
常用的頭部信息
-
Content-type:請求的資源類型對應(yīng)的MIME信息 -
Content-Disposition: disposition-type;filename-parm響應(yīng)請求資源的下載方式- 其中disposition-type可以為
attachment彈出對話框下載,或者inline直接顯示在頁面上 - 其中filename-parm是
filename = xx規(guī)定下載時的文件名,用于規(guī)定下載時的文件名稱
- 其中disposition-type可以為
-
Expires:響應(yīng)過期的日期和時間 -
Location:重定向到url的新的資源 -
Last-modified:請求資源的最后修改日期 -
Content-length:請求的內(nèi)容長度 -
Set-Cookie:設(shè)置cookie
-
-
常用方法
-
parse_header(str)將MIME標頭解析為字典 -
parse_multipart(fp,pdict,encoding =“utf-8”,errors =“replace” )返回{字段名稱:數(shù)據(jù)}的字典 -
print_form(form)將接收的表格以html形式格式化 -
print_directory()以html形式格式化當前目錄 -
test()將cgi作為主程序進行測試
-
-
FieldStorage(,key,filename,value)類- 此類用于獲取html中form輸出的表單數(shù)據(jù),僅需要實例化一次
-
FiledStorage()[key]代表了表單中名為key的標簽整體 -
FiledStorage()[key].value代表了表單中key標簽的值 -
getvalue(key)當有多個值時,返回一個字符串列表 -
getlist(key)返回名key標簽下的所有字符串組成的列表
- 編寫一個最簡單的CGI程序,如果需要訪問該CGI程序,需要先啟動一個CGI服務(wù)器,在前面已經(jīng)學(xué)到過,在
HTTPServer中導(dǎo)入CGIHTTPRequestHandler創(chuàng)建一個最簡單的CGI服務(wù)器
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>My First Python CGI</h1>
</body>
</html>
'''
print(html)
-
CGI獲取客戶端使用
GET方式發(fā)送的數(shù)據(jù)請求的url為
http://127.0.0.1:8888/cgi-bin/cc.py?usr=jack&pwd=123456,可以看出,傳遞的數(shù)據(jù)以明文方式出現(xiàn)在url中傳遞的數(shù)據(jù)包含在請求頭中
在GET方式中,不應(yīng)包含敏感數(shù)據(jù),敏感數(shù)據(jù)應(yīng)使用POST方式發(fā)送
# index.html中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請輸入文字</h1>
<form action="http://127.0.0.1:8888/cgi-bin/cc.py" method="GET" id="myform">
<h2>賬戶:<input type="text" name="usr"></h2>
<h2>密碼:<input type="text" name="pwd"></h2>
<button type="submit">發(fā)送</button>
</form>
</body>
</html>
# CGI程序
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
usr = form.getvalue('usr')
pwd = form.getvalue('pwd')
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>獲取到的數(shù)據(jù)是:</h1>
<p>{0}</p>
<p>{1}</p>
</body>
</html>
'''.format(usr,pwd)
print(html)
-
POST方式在上面的
CGIHTTPRequestHandler中,不多進行贅述- POST方式發(fā)送數(shù)據(jù),不會明文出現(xiàn)在url中,會存在于請求體的form-data中,所以相對于GET方式,要安全的多
- 傳遞checkbox數(shù)據(jù)
# index.html內(nèi)容是
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請勾選</h1>
<form action="/cgi-bin/cc.py" method="POST" id="myform">
<input type="checkbox" name="usr" value="on" > usr
<input type="checkbox" name="pwd" value="on" > pwd
<button type="submit">發(fā)送</button>
</form>
</body>
</html>
# cgi程序
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
google = form.getvalue('google')
if google == on:
r1 = 'google被選中'
else:
r1 = 'google沒有被選中'
baidu = form.getvalue('baidu')
if baidu == 'on':
r2 = 'baidu被選中'
else:
r2 = 'baidu沒有被選中'
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>獲取到的數(shù)據(jù)是:</h1>
<p>{0}</p>
<p>{1}</p>
</body>
</html>
'''.format(r1,r2)
print(html)
- 傳遞radio數(shù)據(jù)
# index.html中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請勾選</h1>
<form action="/cgi-bin/cc.py" method="POST" id="myform">
<input type="radio" name="site" value="google" > 谷歌
<input type="radio" name="site" value="baidu" > 百度
<button type="submit">發(fā)送</button>
</form>
</body>
# cgi程序內(nèi)容
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
value = form.getvalue('site')
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>獲取到的數(shù)據(jù)是:</h1>
<p>{0}</p>
</body>
</html>
'''.format(value)
print(html)
- 傳遞Textatrea數(shù)據(jù)
# index.html中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請輸入內(nèi)容</h1>
<form action="/cgi-bin/cc.py" method="post">
<Textarea name="text" cols="40" rows="4" >在這里輸入內(nèi)容....
</Textarea>
<input type="submit">
</form>
</body>
</html>
# cgi程序中的內(nèi)容
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
value = form.getvalue('text')
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>獲取到的數(shù)據(jù)是:</h1>
<p>{0}</p>
</body>
</html>
'''.format(value)
print(html)
- 傳遞下拉數(shù)據(jù)
# index.html中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請輸入內(nèi)容</h1>
<form action="/cgi-bin/cc.py" method="post">
<select name="sel" >
<option value="baidu">百度</option>
<option value="google">谷歌</option>
</select>
<input type="submit">
</form>
</body>
</html>
# cgi程序中的內(nèi)容
import cgi
import cgitb
cgitb.enable()
print("Content-Type: text/html")
print()
form = cgi.FieldStorage()
value = form.getvalue('sel')
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>獲取到的數(shù)據(jù)是:</h1>
<p>{0}</p>
</body>
</html>
'''.format(value)
print(html)
- 設(shè)置cookie
# 直接訪問cgi程序,設(shè)置cookie,通過chrome即可查看設(shè)置的cookie
# cgi程序為:
import cgi,datetime
import cgitb
from http.cookies import *
cgitb.enable()
name = 'cgicookie'
now = datetime.datetime.utcnow()
time = (now + datetime.timedelta(days=10)).strftime('%a,%d-%m-%Y %H:%M:%S')
path = '/'
domain = '127.0.0.1'
cookie = SimpleCookie()
cookie['NAME'] = name
cookie['NAME']['expires'] = time
cookie['NAME']['path'] = path
cookie['NAME']['domain'] = domain
print("Content-Type: text/html")
print(cookie)
print()
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>cookie已經(jīng)設(shè)置</h1>
</body>
</html>
'''
print(html)
- 文件上傳
# index.html中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>文件上傳</h1>
<form action="/cgi-bin/cc.py" method="post" enctype="multipart/form-data">
<p><input type="file" name="upload"></p>
<p><input type="submit"></p>
</form>
</body>
</html>
# cgi程序為:
import cgi
import cgitb
cgitb.enable()
form = cgi.FieldStorage()
file = form['upload']
open(file.filename,'wb').write(file.value)
print("Content-Type: text/html")
print()
html ='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>已接收上傳文件</h1>
</body>
</html>
'''
print(html)
- 文件下載
# 直接訪問cgi程序,以下為cgi程序的內(nèi)容
import cgi
import cgitb
cgitb.enable()
data = open(r'chromedriver.exe','rb').read()
print("Content-Disposition: attachment;filename=chromedriver.exe")
print()
print(data)
urlib URL處理模塊
-
url 同一資源定位符
-
格式:
prot_sch://net_loc/path;params?query#fragprot_sch 網(wǎng)絡(luò)協(xié)議
-
net_loc服務(wù)器所在地址 可進一步分割為多個組件-
user用戶名 -
passwd用戶密碼 -
host服務(wù)器所在地址或服務(wù)器計算機名稱(必須) -
port端口號(默認80)
-
path文件或者CGI應(yīng)用的路徑params可選參數(shù)query連接符(&)分割的鍵值對frag文檔中的特定錨點
-
-
request請求url模塊-
Request(url,data = None,headers = {})類 構(gòu)造一個復(fù)雜的請求對象,可以供urlopen函數(shù)使用full_url返回請求的urlhost返回請求的主機地址method返回請求的方法add_header(key,value)添加請求標頭has_header(key)檢查是否有key請求標頭remove_header(key)刪除名為key的請求標頭get_header(key)返回名為key的標頭值header_items()返回所有請求標頭和值
-
-
urlopen(url,data)打開一個url,發(fā)送data,返回HTTPResponse對象在HTTPResponse的基礎(chǔ)上添加了以下方法
geturl()返回請求資源的urlinfo()返回頁面的元信息getcode()返回響應(yīng)的狀態(tài)碼
build_opener([handler,])返回一個OpenerDirector對象install_opener(OpenerDirector對象)將OpenerDirector對象設(shè)置為全局默認-
OpenerDirector類 該類主要用于通過添加相應(yīng)的Handler構(gòu)建一個自定義的urlopen對象,實現(xiàn)各種不同的訪問需求add_handler(Handler)添加一個處理行為給OpenerDirector對象open(url)打開URL,返回HTTPResponse對象error(proto,* args)給定相應(yīng)的參數(shù)處理錯誤
HTTPRedirectHandler類,重定向處理程序HTTPHandler類,發(fā)送HTTP請求,可以為GET或POSTHTTPSHandler(debuglevel = 0,context = None,check_hostname = None )類,發(fā)送HTTPS請求,可以為GET或者POSTHTTPBasicAuthHandler(password_mgr = None )類,請求時需要賬戶密碼登錄ProxyHandler(proxies = None )類,代理請求,需要在實例化的時候添加代理字典ProxyBasicAuthHandler(password_mgr = None )類,需要用戶名密碼登錄的代理HTTPCookieProcessor(cookiejar)類,Cookie處理FileHandler類,打開文件FTPHandler類,打開FTP文件-
HTTPErrorProcessor類,處理HTTP異常http_response(req,reply)對于錯誤,返回reply對象https_response(req,reply)對于錯誤,返回reply對象
-
密碼管理器對象,用于添加到各項需要認證的處理程序中
-
HTTPPasswordMgr類,映射數(shù)據(jù)庫,通過(realm, uri) -> (user, password)add_password(realm, uri, user, passwd)添加相應(yīng)的賬戶,密碼到管理器對象中,realm是指主機服務(wù)器的域信息一般為None,uri指服務(wù)器find_user_password(realm, authuri)返回指定服務(wù)器域中是否有定義的賬戶,如果有返回(賬戶,密碼)元組,沒有返回None
-
HTTPPasswordMgrWithDefaultRealm類- 同上兩個方法
HTTPPasswordMgrWithPriorAuth類同上兩個方法
update_authenticated(self, uri, is_authenticated=False)is_authenticated(self, authuri)
-
使用默認函數(shù)訪問url
from urllib.request import *
url = 'http://www.baidu.com'
response = urlopen(url)
print(response.read().decode())
使用Request對象構(gòu)造請求
from urllib.request import *
url = 'http://www.baidu.com'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36',
'Host': 'www.baidu.com'
}
request = Request(url,headers=headers)
response = urlopen(request)
print(response.read().decode())
構(gòu)造自定的訪問器,獲取cookie
from urllib.request import *
from http.cookiejar import *
url = 'http://www.baidu.com'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36',
'Host': 'www.baidu.com'
}
cookie = CookieJar()
openr = build_opener(HTTPCookieProcessor(cookie))
request = Request(url,headers=headers)
response = openr.open(request)
print(cookie)
print(response.read().decode())
# 或者
from urllib.request import *
from http.cookiejar import *
url = 'http://www.baidu.com'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36',
'Host': 'www.baidu.com'
}
cookie = CookieJar()
openr = OpenerDirector()
openr.add_handler(HTTPCookieProcessor(cookie))
openr.add_handler(HTTPHandler())
request = Request(url,headers=headers)
response = openr.open(request)
print(cookie)
構(gòu)造自定訪問器,使用用戶名、密碼登錄
from urllib.request import *
from urllib.parse import *
login_url = r'https://www.douban.com/accounts/login'
data = urlencode({
'source': 'index_nav',
'form_email': 'XXXXX',
'form_password': 'XXXXX'
}).encode()
request = Request(url=login_url,data=data)
response = urlopen(request)
print(response.read().decode('utf-8','ignore'))



