pythonhttpresponse
根據Testcase的具體業務邏輯用事先准備好的測試數據去調用封裝好的API介面,驗證實際返回結果是否與預期返回結果一致.
測試數據可以以各種形式存放,如Excel數據表:
TestCaseName uname method Expected Result
TestCase1 aaaa GET ....
TestCase2 aaaa POST ....
TestCase3 bbbb GET ....
... ... ... ....
⑵ python 怎樣獲取http響應的session
對象基本上就是一個字典 把它轉換成一個包含元組的列表,然後用合適的分隔符連接起來就好了 1 2 3 4 5 import requests resp = requests.get(url) cookies = resp.cookies print('; '.join(['='.join(item) for
⑶ python怎麼截取http請求
import httplib, urllib
from urlparse import urlparse
def httppost(url, **kwgs):
httpClient = None
conn = urlparse(url)
try:
params = urllib.urlencode(dict(kwgs))
header = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain", }
httpClient = httplib.HTTPConnection(conn.netloc, conn.port, timeout=30)
httpClient.request("POST", conn.path, params, header)
response = httpClient.getresponse()
print response.status
print response.reason
print response.read()
print response.getheaders()
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
⑷ python http requests 怎麼實現模擬登錄,提交表單
以下實例是一個完整的代碼,實現了從博客獲取內容發布至網路,分別實踐抓取博客內容、模擬登錄、表單提交這幾步;
#注意,以下程序是一個完全程序,如果只需要實現模擬登錄,提交表單,刪除抓取部分即可,相關的代碼已經清楚標注,可以根據自己實際情況修改。
代碼如下:
# -*- coding: utf-8 -*-
import re
import urllib
import urllib2
import cookielib
#第一步,獲取博客標題和正文 ,「IP」可以改為實際地址;
url = "IP"
sock = urllib.urlopen(url)
html = sock.read()
sock.close()
content = re.findall('(?<=blogstory">).*(?=<p class="right artical)', html, re.S)
content = re.findall('<script.*>.*</script>(.*)', content[0], re.S)
title = re.findall('(?<=<title>)(.*)-.* - CSDN.*(?=</title>)', html, re.S)
#根據文章獲取內容新建表單值
blog = {'spBlogTitle': title[0].decode('utf-8').encode('gbk'), #文章標題
'spBlogText': content[0].decode('utf-8').encode('gbk'),#文章內容
'ct': "1",
'cm': "1"}
del content
del title
#第二步,模擬登錄網路;
cj = cookielib.CookieJar()
#登陸網路的用戶名和密碼
post_data = urllib.urlencode({'username': '[username]', 'password': '[password]', 'pwd': '1'})
#登錄地址路徑
path = 'https://passport..com/?login'
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders = [('User-agent', 'Opera/9.23')]
urllib2.install_opener(opener)
req = urllib2.Request(path, post_data)
conn = urllib2.urlopen(req)
#獲取網路登陸認證令牌
bd = urllib2.urlopen(urllib2.Request('http://hi..com/[username]/creat/blog')).read()
bd = re.findall('(?<=bdstoken\" value=\").*(?=ct)', bd, re.S)
blog['bdstoken'] = bd[0][:32]
#設置分類名
blog['spBlogCatName'] = 'php'
#第四步,比較表單,提交表單;req2 = urllib2.Request('http://hi..com/[username]/commit', urllib.urlencode(blog))
#最後,查看錶單提交後返回內容,檢驗;
print urllib2.urlopen(req2).read()
#注意:將[username]/[password]替換為自己真實用戶名和密碼
⑸ python怎樣接收http協議返回的一個zip包
從頭開始,找到兩個換行符(前面是HEADER,包括伺服器、日期、長度、是否支持斷點等信息),後面的就是文件內容了.
⑹ python http怎麼加入epoll
介紹
從2.6版本開始, python 提供了使用linux epoll 的功能. 這篇文章通過3個例子來大致介紹如何使用它. 歡迎提問和反饋.
阻塞式socket通訊
第一個例子是一個簡單的python3.0版本的伺服器代碼, 監聽8080埠的http請求, 列印結果到命令行, 回應http response給客戶端.
行 9: 建立伺服器的socket
行 10: 允許11行的bind()操作, 即使其他程序也在監聽同樣的埠. 不然的話, 這個程序只能在其他程序停止使用這個埠之後的1到2分鍾後才能執行.
行 11: 綁定socket到這台機器上所有IPv4地址上的8080埠.
行 12: 告訴伺服器開始響應從客戶端過來的連接請求.
行 14: 程序會一直停在這里, 直到建立了一個連接. 這個時候, 伺服器socket會建立一個新的socket, 用來和客戶端通訊. 這個新的socket是accept()的返回值, address對象標示了客戶端的IP地址和埠.
行 15-17: 接收數據, 直到一個完整的http請求被接收完畢. 這是一個簡單的http伺服器實現.
行 18: 為了方便驗證, 列印客戶端過來的請求到命令行.
行 19: 發送回應.
行 20-22: 關閉連接, 以及伺服器的監聽socket.
Example1:
import socketEOL1 = b'\n\n'EOL2 = b'\n\r\n'response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 8080))
serversocket.listen(1)
connectiontoclient, address = serversocket.accept()
request = b''while EOL1 not in request and EOL2 not in request:
request += connectiontoclient.recv(1024)print(request.decode())
connectiontoclient.send(response)
connectiontoclient.close()
serversocket.close()
第2個例子, 我們在15行加上了一個循環, 用來循環處理客戶端請求, 直到我們中斷這個過程(在命令行下面輸入鍵盤中斷, 比如Ctrl-C). 這個例子更明顯地表示出來了, 伺服器socket並沒有用來做數據處理, 而是接受伺服器過來的連接, 然後建立一個新的socket, 用來和客戶端通訊.
最後的23-24行確保伺服器的監聽socket最後總是close掉, 即使出現了異常.
Example 2:
import socketEOL1 = b'\n\n'EOL2 = b'\n\r\n'response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 8080))
serversocket.listen(1)
try: while True:
connectiontoclient, address = serversocket.accept()
request = b''
while EOL1 not in request and EOL2 not in request:
request += connectiontoclient.recv(1024) print('-'*40 + '\n' + request.decode()[:-2])
connectiontoclient.send(response)
connectiontoclient.close()
finally:
serversocket.close()24
非同步socket和linux epoll的優勢
第2個例子裡面的socket採用的是阻塞方式, 因為python解釋器在出現事件之前都處在停止狀態. 16行的accept()一直阻塞, 直到新的連接進來. 19行的recv()也是一直阻塞, 直到從客戶端收到數據(或者直到沒有數據可以接收). 21行的send()也一直阻塞, 直到所有需要發送給客戶端的數據都交給了linux內核的發送隊列.
當一個程序採用阻塞socket的時候, 它經常採用一個線程(甚至一個進程)一個socket通訊的模式. 主線程保留伺服器監聽socket, 接受進來的連接, 一次接受一個連接, 然後把生成的socket交給一個分離的線程去做交互. 因為一個線程只和一個客戶端通訊, 在任何位置的阻塞都不會造成問題. 阻塞本身不會影響其他線程的工作.
多線程阻塞socket模式代碼清晰, 但是有幾個缺陷, 可能很難確保線程間資源共享工作正常, 可能在只有一個CPU的機器上效率低下.
C10K(單機1萬連接問題!) 探討了其他處理並行socket通訊的模式. 一種是採用非同步socket. socket不會阻塞, 直到特定事件發生. 程序在非同步socket上面進行一個特定操作, 並且立即得到一個結果, 不管執行成功或者失敗. 然後讓程序決定下一步怎麼做. 因為非同步socket是非阻塞的, 我們可以不採用多線程. 所有的事情都可以在一個線程裡面完成. 雖然這種模式有它需要面對的問題, 它對於特定程序來說還是不錯的選擇. 也可以和多線程合起來使用: 單線程的非同步socket可以當作伺服器上面處理網路的一個模塊, 而線程可以用來訪問阻塞式的資源, 比如資料庫.
Linux 2.6有一些方式來管理非同步socket, python API能夠用的有3種: select, poll和epoll. epoll和poll比select性能更好, 因為python程序不需要為了特定的事件去查詢單獨的socket, 而是依賴操作系統來告訴你什麼socket產生了什麼事件. epoll比poll性能更好, 因為它不需要每次python程序查詢的時候, 操作系統都去檢查所有的socket, 在事件產生的時候, linux跟蹤他們, 然後在python程序調用的時候, 返回具體的列表. 所以epoll在大量(上千)並行連接下, 是一種更有效率, 伸縮性更強的機制.
採用epoll的非同步socket編程示例
採用epoll的程序一般這樣操作:
建立一個epoll對象
告訴epoll對象, 對於一些socket監控一些事件.
問epoll, 從上次查詢以來什麼socket產生了什麼事件.
針對這些socket做特定操作.
告訴epoll, 修改監控socket和/或監控事件.
重復第3步到第5步, 直到結束.
銷毀epoll對象.
採用非同步socket的時候第3步重復了第2步的事情. 這里的程序更復雜, 因為一個線程需要和多個客戶端交互.
行 1: select模塊帶有epoll功能
行 13: 因為socket默認是阻塞的, 我們需要設置成非阻塞(非同步)模式.
行 15: 建立一個epoll對象.
行 16: 注冊伺服器socket, 監聽讀取事件. 伺服器socket接收一個連接的時候, 產生一個讀取事件.
行 19: connections表映射文件描述符(file descriptors, 整型)到對應的網路連接對象上面.
行 21: epoll對象查詢一下是否有感興趣的事件發生, 參數1說明我們最多等待1秒的時間. 如果有對應事件發生, 立刻會返回一個事件列表.
行 22: 返回的events是一個(fileno, event code)tuple列表. fileno是文件描述符, 是一個整型數.
行 23: 如果是伺服器socket的事件, 那麼需要針對新的連接建立一個socket.
行 25: 設置socket為非阻塞模式.
行 26: 注冊socket的read(EPOLLIN)事件.
行 31: 如果讀取事件發生, 從客戶端讀取新數據.
行 33: 一旦完整的http請求接收到, 取消注冊讀取事件, 注冊寫入事件(EPOLLOUT), 寫入事件在能夠發送數據回客戶端的時候產生.
行 34: 列印完整的http請求, 展示即使通訊是交錯的, 數據本身是作為一個完整的信息組合和處理的.
行 35: 如果寫入事件發生在一個客戶端socket上面, 我們就可以發送新數據到客戶端了.
行s 36-38: 一次發送一部分返回數據, 直到所有數據都交給操作系統的發送隊列.
行 39: 一旦所有的返回數據都發送完, 取消監聽讀取和寫入事件.
行 40: 如果連接被明確關閉掉, 這一步是可選的. 這個例子採用這個方法是為了讓客戶端首先斷開, 告訴客戶端沒有數據需要發送和接收了, 然後讓客戶端斷開連接.
行 41: HUP(hang-up)事件表示客戶端斷開了連接(比如 closed), 所以伺服器這端也會斷開. 不需要注冊HUP事件, 因為它們都會標示到注冊在epoll的socket.
行 42: 取消注冊.
行 43: 斷開連接.
行s 18-45: 在這里的異常捕捉的作用是, 我們的例子總是採用鍵盤中斷來停止程序執行.
行s 46-48: 雖然開啟的socket不需要手動關閉, 程序退出的時候會自動關閉, 明確寫出來這樣的代碼, 是更好的編碼風格.
Example 3:
import socket, selectEOL1 = b'\n\n'EOL2 = b'\n\r\n'response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 8080))
serversocket.listen(1)
serversocket.setblocking(0)
epoll = select.epoll()
epoll.register(serversocket.fileno(), select.EPOLLIN)
try:
connections = {}; requests = {}; responses = {} while True:
events = epoll.poll(1) for fileno, event in events: if fileno == serversocket.fileno():
connection, address = serversocket.accept()
connection.setblocking(0)
epoll.register(connection.fileno(), select.EPOLLIN)
connections[connection.fileno()] = connection
requests[connection.fileno()] = b''
responses[connection.fileno()] = response
elif event & select.EPOLLIN:
requests[fileno] += connections[fileno].recv(1024) if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
epoll.modify(fileno, select.EPOLLOUT) print('-'*40 + '\n' + requests[fileno].decode()[:-2])
elif event & select.EPOLLOUT:
byteswritten = connections[fileno].send(responses[fileno])
responses[fileno] = responses[fileno][byteswritten:] if len(responses[fileno]) == 0:
epoll.modify(fileno, 0)
connections[fileno].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLHUP:
epoll.unregister(fileno)
connections[fileno].close()
del connections[fileno]
finally:
epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()
epoll有2種模式, 邊沿觸發(edge-triggered)和狀態觸發(level-triggered). 邊沿觸發模式下, epoll.poll()在讀取/寫入事件發生的時候只返回一次, 程序必須在後續調用epoll.poll()之前處理完對應事件的所有的數據. 當從一個事件中獲取的數據被用完了, 更多在socket上的處理會產生異常. 相反, 在狀態觸發模式下面, 重復調用epoll.poll()只會返回重復的事件, 直到所有對應的數據都處理完成. 一般情況下不產生異常.
比如, 一個伺服器socket注冊了讀取事件, 邊沿觸發程序需要調用accept建立新的socket連接直到一個socket.error錯誤產生, 然後狀態觸發下只需要處理一個單獨的accept(), 然後繼續epoll查詢新的事件來判斷是否有新的accept需要操作.
例子3採用默認的狀態觸發模式, 例子4展示如何用邊沿觸發模式. 例子4中的25, 36和45行引入了循環, 直到錯誤產生(或者所有的數據都處理完了), 32, 38 和48行捕捉socket異常. 最後16, 28, 41 和51行添加EPOLLET mask用來設置邊沿觸發.
Example 4:
import socket, selectEOL1 = b'\n\n'EOL2 = b'\n\r\n'response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 8080))
serversocket.listen(1)
serversocket.setblocking(0)
epoll = select.epoll()
epoll.register(serversocket.fileno(), select.EPOLLIN | select.EPOLLET)
try:
connections = {}; requests = {}; responses = {} while True:
events = epoll.poll(1) for fileno, event in events: if fileno == serversocket.fileno():
try: while True:
connection, address = serversocket.accept()
connection.setblocking(0)
epoll.register(connection.fileno(), select.EPOLLIN | select.EPOLLET)
connections[connection.fileno()] = connection
requests[connection.fileno()] = b''
responses[connection.fileno()] = response
except socket.error:
pass
elif event & select.EPOLLIN:
try: while True:
requests[fileno] += connections[fileno].recv(1024)
except socket.error:
pass if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
epoll.modify(fileno, select.EPOLLOUT | select.EPOLLET) print('-'*40 + '\n' + requests[fileno].decode()[:-2])
elif event & select.EPOLLOUT:
try: while len(responses[fileno]) > 0:
byteswritten = connections[fileno].send(responses[fileno])
responses[fileno] = responses[fileno][byteswritten:]
except socket.error:
pass if len(responses[fileno]) == 0:
epoll.modify(fileno, select.EPOLLET)
connections[fileno].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLHUP:
epoll.unregister(fileno)
connections[fileno].close()
del connections[fileno]
finally:
epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()
因為比較類似, 狀態觸發經常用在轉換採用select/poll模式的程序上面, 邊沿觸發用在程序員不需要或者不希望操作系統來管理事件狀態的場合上面.
除了這兩種模式以外, socket經常注冊為EPOLLONESHOT event mask, 當用到這個選項的時候, 事件只有效一次, 之後會自動從監控的注冊列表中移除.
⑺ python2.7 中 response.read()返回的是一個httpresponse對象還是一個html對象
返回的是html字元串類型。
⑻ python requests http響應嗎
Requests 使用的是 urllib3,因此繼承了它的所有特性。Requests 支持 HTTP 連接保持和連接池,支持使用 cookie 保持會話,支持文件上傳,支持自動確定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。
⑼ 怎麼知道python發送了什麼http請求
本文實例講述了python通過get,post方式發送http請求和接收http響應的方法。分享給大家供大家參考。具體如下:
測試用CGI,名字為test.py,放在apache的cgi-bin目錄下:
#!/usr/bin/python
import cgi
def main():
print "Content-type: text/html\n"
form = cgi.FieldStorage()
if form.has_key("ServiceCode") and form["ServiceCode"].value != "":
print "<h1> Hello",form["ServiceCode"].value,"</h1>"
else:
print "<h1> Error! Please enter first name.</h1>"
main()
python發送post和get請求
get請求:
使用get方式時,請求數據直接放在url中。
方法一、
import urllib
import urllib2
url = "test.py?ServiceCode=aaaa"
req = urllib2.Request(url)
print req
res_data = urllib2.urlopen(req)
res = res_data.read()
print res
方法二、
import httplib
url = "hest/test.py?ServiceCode=aaaa"
conn = httplib.HTTPConnection("192.168.81.16")
conn.request(method="GET",url=url)
response = conn.getresponse()
res= response.read()
print res
post請求:
使用post方式時,數據放在data或者body中,不能放在url中,放在url中將被忽略。
方法一、
import urllib
import urllib2
test_data = {'ServiceCode':'aaaa','b':'bbbbb'}
test_data_urlencode = urllib.urlencode(test_data)
requrl = "/python_test/test.py"
req = urllib2.Request(url = requrl,data =test_data_urlencode)
print req
res_data = urllib2.urlopen(req)
res = res_data.read()
print res
方法二、
import urllib
import httplib
test_data = {'ServiceCode':'aaaa','b':'bbbbb'}
test_data_urlencode = urllib.urlencode(test_data)
requrl = "python_test/test.py"
headerdata = {"Host":"116"}
conn = httplib.HTTPConnection("192.168.81.16")
conn.request(method="POST",url=requrl,body=test_data_urlencode,headers = headerdata)
response = conn.getresponse()
res= response.read()
print res
對python中json的使用不清楚,所以臨時使用了urllib.urlencode(test_data)方法;
模塊urllib,urllib2,httplib的區別
httplib實現了http和https的客戶端協議,但是在python中,模塊urllib和urllib2對httplib進行了更上層的封裝。
介紹下例子中用到的函數:
1、HTTPConnection函數
httplib.HTTPConnection(host[,port[,stict[,timeout]]])
這個是構造函數,表示一次與伺服器之間的交互,即請求/響應
host 標識伺服器主機(伺服器IP或域名)
port 默認值是80
strict 模式是False,表示無法解析伺服器返回的狀態行時,是否拋出BadStatusLine異常
例如:
conn = httplib.HTTPConnection("1.16",80) 與伺服器建立鏈接。
2、HTTPConnection.request(method,url[,body[,header]])函數
這個是向伺服器發送請求
method 請求的方式,一般是post或者get,
例如:
method="POST"或method="Get"
url 請求的資源,請求的資源(頁面或者CGI,我們這里是CGI)
例如:
url="htti-bin/python_test/test.py" 請求CGI
或者
url="ht_test/test.html" 請求頁面
body 需要提交到伺服器的數據,可以用json,也可以用上面的格式,json需要調用json模塊
headers 請求的http頭headerdata = {"Host":"192.168.81.16"}
例如:
test_data = {'ServiceCode':'aaaa','b':'bbbbb'}
test_data_urlencode = urllib.urlencode(test_data)
requrl = "hgi-bin/python_test/test.py"
headerdata = {"Host":"192.116"}
conn = httplib.HTTPConnection("196",80)
conn.request(method="POST",url=requrl,body=test_data_urlencode,headers = headerdata)
conn在使用完畢後,應該關閉,conn.close()
3、HTTPConnection.getresponse()函數
這個是獲取http響應,返回的對象是HTTPResponse的實例。
4、HTTPResponse介紹:
HTTPResponse的屬性如下:
read([amt]) 獲取響應消息體,amt表示從響應流中讀取指定位元組的數據,沒有指定時,將全部數據讀出;
getheader(name[,default]) 獲得響應的header,name是表示頭域名,在沒有頭域名的時候,default用來指定返回值
getheaders() 以列表的形式獲得header
例如:
date=response.getheader('date');
print date
resheader=''
resheader=response.getheaders();
print resheader
列形式的響應頭部信息:
[('content-length', '295'), ('accept-ranges', 'bytes'), ('server', 'Apache'), ('last-modified', 'Sat, 31 Mar 2012 10:07:02 GMT'), ('connection', 'close'), ('etag', '"e8744-127-4bc871e4fdd80"'), ('date', 'Mon, 03 Sep 2012 10:01:47 GMT'), ('content-type', 'text/html')]
date=response.getheader('date');
print date
取出響應頭部的date的值。
⑽ python http請求時使用GET返回成功,使用POST卻返回失敗
看來你是對於網頁抓取的邏輯不太熟悉,所以自己先去看看:
【整理】關於抓取網頁,分析網頁內容,模擬登陸網站的邏輯/流程和注意事項
看懂了邏輯後,再去學慣用工具如何抓取出來相關的邏輯:
【教程】手把手教你如何利用工具(IE9的F12)去分析模擬登陸網站(網路首頁)的內部邏輯過程
最後,再學習如何用python語言實現這些邏輯:
【教程】抓取網並提取網頁中所需要的信息 之 Python版
【教程】模擬登陸網站 之 Python版(內含兩種版本的完整的可運行的代碼)
(這里不給貼地址,自己或google搜標題即可找到我的這些帖子)