http://docs.python-requests.org/en/master/html
http://www.kennethreitz.orgpython
https://github.com/requests/requestslinux
python、pipgit
注:pip freeze -- 查看當前已經安裝的pip包github
做用json
初始化一個空環境(也能夠不初始化)windows
使用 pip / easy_install 是爲了可以良好的管理起來你的包,這相似deb之流。api
之因此須要用 VirtualEnv,關鍵的目的是把你當前開發/生產的 Python 環境和其餘的 Python 環境隔離開來。例如你的 Proj1 須要用到 LibA 的版本1.0,而你的 Proj2 須要用到LibA的2.0,若是不加以區分,那麼就會可能形成衝突。瀏覽器
在 VirtualEnv 中,每個 VirtualEnv 的環境,都是隔離的,須要的包等都是單獨的,你能夠認爲這是一個沙盒(SandBox),這時候 pip / easy_install 等運行時候依賴的 Python 也是隔離的,既 $VENV_HOME/bin/python 而非 /usr/bin/python。安全
通常的,yum / apt 安裝的會安裝在系統的路徑中,針對 Python, 則是 Global 的 PYTHONPATH。很難作到隔離。
而從源代碼安裝的,通常的會根據你的運行時 Python 命令進行隔離。也就是若是你啓用了 VirtualEnv (source $VENV_HOME/bin/activate)後,從源碼安裝的也會在這個 venv 下。
安裝virtualenv
pip install virtualenv
使用virtualenv初始化當前文件夾
virtualenv .env
激活當前文件夾的virtualenv
windows:.env/Script/activate
linux:source .env/bin/activate
注:deactivate能夠退出虛擬環境
pip install requests
測試用,因爲http://httpbin.org/服務器在美國,因此能夠在本地搭建個相似環境測試
pip install gunicorn httpbin
gunicorn httpbin:app
注:windows上沒法安裝gunicorn
HyperText Transfer Protocol超文本傳輸協議
The Hypertext Transfer Protocol is a stateless(無狀態的), application-level protocol(應用層協議) for distributed(分佈式), collaborative(協做式), hepertext information system(超文本信息系統)
curl -v https://www.imooc.com/ >/data01/yc_files/http_contact_demo.log
python原生網絡庫
urllib和urllib2是獨立的模塊,並無直接的關係,二者相互結合實現複雜的功能
urllib和urllib2在python2中才可使用
requests庫中使用了urllib3(屢次請求重複使用一個socket)
urlib_demo
# -*- coding:utf-8 -*- import urllib2 import urllib URL_simple="http://httpbin.org/ip" URL_get="http://httpbin.org/get" def urllib_simple_use(): response = urllib2.urlopen(URL_simple) print( '>>>>Response Headers:') print( response.info()) print( '>>>>Response Status Code:') print( response.getcode()) print( '>>>>Response :') print( ''.join([line for line in response])) def urllib_params_use(): params = urllib.urlencode({'param1':'hello','param2':'world'}) response = urllib2.urlopen('?'.join([URL_get,params])) print( '>>>>Response Headers:') print( response.info()) print( '>>>>Response Status Code:') print( response.getcode()) print( '>>>>Response :') print( ''.join([line for line in response])) if __name__ == '__main__': print( '>>>>Urllib Simple Use:') urllib_simple_use() print( '>>>>Urllib Params Use:') urllib_params_use()
requests_demo
quick start: http://docs.python-requests.org/en/latest/user/quickstart/
# -*- coding:utf-8 -*- import requests URL_simple="http://httpbin.org/ip" URL_get="http://httpbin.org/get" def requests_simple_use(): response = requests.get(URL_simple) print( '>>>>Request Headers:') print( response.request.headers) print( '>>>>Request body:') print( response.request.body) print( '>>>>Response url:') print( response.url) print( '>>>>Response Headers:') print( response.headers) print( '>>>>Response Status Code:') print( response.status_code) print( '>>>>Response Status Code Reason:') print( response.reason) print( '>>>>Response :') print( response.text) print( response.json()) def requests_params_use(): params = {'param1':'hello','param2':'world'} response = requests.get(URL_get,params=params) print( '>>>>Request Headers:') print( response.request.headers) print( '>>>>Request body:') print( response.request.body) print( '>>>>Response url:') print( response.url) print( '>>>>Response Headers:') print( response.headers) print( '>>>>Response Status Code:') print( response.status_code) print( '>>>>Response Status Code Reason:') print( response.reason) print( '>>>>Response :') print( response.text) print( response.json()) if __name__ == '__main__': print( '>>>>Requests Simple Use:') requests_simple_use() print( '>>>>Requests Params Use:') requests_params_use()
擴展
RFC7230 -> RFC7235閱讀
import requests import json from requests.exceptions import RequestException ROOT_URL='https://api.github.com' def better_print(src_json): ''' 格式化打印json ''' return json.dumps(src_json,indent=4) def get_simple_use(): ''' API得到指定用戶的用戶信息 ''' response = requests.get('/'.join([ROOT_URL,'users/wahaha'])) print('>>>>Response text:') print(better_print(response.json())) def get_auth_use(): ''' API得到指定用戶的email信息--明文,不建議方法。 固然,123456是錯誤的密碼。 建議經過簡易oauth認證。 ''' # response = requests.get('/'.join([ROOT_URL,'user/emails'])) response = requests.get('/'.join([ROOT_URL,'user/emails']),auth=('wahaha','123456')) print('>>>>Response text:') print(better_print(response.json())) def get_params_use(): ''' get + 帶參URL 得到11號以後的user信息 ''' response = requests.get('/'.join([ROOT_URL,'users']),params={'since':11}) print( '>>>>Request Headers:') print( response.request.headers) print( '>>>>Request body:') print( response.request.body) print( '>>>>Response url:') print( response.url) print('>>>>Response text:') print(better_print(response.json())) def patch_json_use(): ''' json參數 + patch 修改用戶郵箱 ''' response = requests.patch('/'.join([ROOT_URL,'user']),auth=('wahaha','123456'),json={'name':'test_name','email':'hello-world@163.com'}) print( '>>>>Request Headers:') print( response.request.headers) print( '>>>>Request body:') print( response.request.body) print( '>>>>Response url:') print( response.url) print('>>>>Response text:') print(better_print(response.json())) def request_exception_use(): ''' 設定超時時間 + 異常處理 timeout = x 握手+發送response超時時間-x timeout = ( x, y) 握手超時時間-x, 發送response超時時間-y ''' try: response = requests.get('/'.join([ROOT_URL,'users']),timeout=(0.1,0.2),params={'since':11}) except RequestException as e: print(e) else: print( '>>>>Request Headers:') print( response.request.headers) print( '>>>>Request body:') print( response.request.body) print( '>>>>Response url:') print( response.url) print('>>>>Response text:') print(better_print(response.json())) def my_request_use(): ''' 簡單模擬requests庫底層實現發送requset方法 ''' # 導庫 from requests import Request,Session # 初始化session my_session = Session() # 初始化headers my_headers = {'User-Agent':'fake1.1.1'} # 初始化request my_request = Request('GET','/'.join([ROOT_URL,'users']),headers=my_headers, params={'since':'11'}) # 準備request my_prepared_request = my_request.prepare() # 發送request,並用response接受 my_response = my_session.send(my_prepared_request,timeout=(3,3)) print( '>>>>Request Headers:') print( json.dumps(dict(my_response.request.headers),indent=4)) print( '>>>>Request body:') print( my_response.request.body) print( '>>>>Response url:') print( my_response.url) print( '>>>>Response Headers:') print( json.dumps(dict(my_response.headers),indent=4)) print( '>>>>Response Status Code:') print( my_response.status_code) print( '>>>>Response Status Code Reason:') print( my_response.reason) # print( '>>>>Response :') # print(better_print(my_response.json())) def hook_function(response, *args, **kw): print ('回調函數>>>',response.headers['Content-Type']) def event_hook_use(): ''' 事件鉤子,即回調函數,指定得到response時候調用的函數 ''' response = requests.get('http://www.baidu.com',hooks={'response':hook_function}) if __name__=="__main__": # get_simple_use() # get_auth_use() # get_params_use() # patch_json_use() # request_exception_use() # my_request_use() event_hook_use()
不一樣網站接口所對應的發送請求所需的參數類型不一樣
https://developer.github.com/v3/#parameters
1.URL參數
https://xxx/xx?a=1&b=2&c=3
request庫中使用requests.get(url, params={'a':'1','b':'2','c':'3'})
優點:跳轉方便,速度快
劣勢:明文,長度有限制
2.表單參數提交
Content-Type: application/x-www-form-urlencoded
request庫中使用requests.post(url, data={'a':'1','b':'2','c':'3'})
3.json參數提交
Content-Type: application/json
request庫中使用request.post(url, json={'a':'1','b':'2','c':'3'})
使用參考:https://developer.github.com/v3/guides/getting-started/
GET -- 查看資源
POST -- 增長資源
PATCH -- 修改資源
PUT -- 修改資源(比PATCH修改的力度大)
DELETE -- 刪除資源
HEAD -- 查看響應頭
OPTIONS -- 查看可用請求方法
requests庫中顯示引起的全部異常都繼承自requests.exceptions.RequestException,因此直接捕獲該異常便可。
git@github.com:requests/requests.git
經過閱讀request源碼,瞭解Session(proxy,timeout,verify)、PreparedRequest(body,headers,auth)、Response(text,json...)
響應的附加信息
status_code 響應碼 E:\yc_study\python\request\request\HTTP狀態碼.html
reason 響應碼解釋
headers 響應頭
url 該響應是從哪一個url發來的
history 重定向的歷史信息
elapsed 接口調用時長
request 該響應對應的request
響應的主體內容
encoding 主體內容的編碼格式
content 主體內容,str類型
text 主體內容,unicode類型
json 主體內容,json類型
raw 流模式下,返回一個urllib3.response.HTTPResponse類型的對象,能夠分塊取出數據
>>> r = requests.get('https://api.github.com/events', stream=True) >>> r.raw <requests.packages.urllib3.response.HTTPResponse object at 0x101194810> >>> r.raw.read(10) '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
iter_content 流模式下,返回字節碼,但會自動解碼,能夠分塊取出數據
with open(filename, 'wb') as fd: for chunk in r.iter_content(chunk_size=128): fd.write(chunk)
注1:iter_content和raw的區別
使用Response.iter_content會處理不少你直接使用Response.raw時必須處理的內容。在流式傳輸下載時,以上是檢索內容的首選和推薦方式。請注意,chunk_size能夠隨意調整爲更適合您的用例的數字。
Response.iter_content會自動解碼gzip和deflate傳輸編碼。Response.raw是一個原始的字節流,它不轉換響應內容。若是您確實須要訪問返回的字節,請使用Response.raw。
注2:使用流模式讀取文件時,最終須要關閉流
http://www.cnblogs.com/Security-Darren/p/4196634.html
# -*- coding:utf-8 -*- def get_image(img_url): import requests # response = requests.get(img_url,stream=True) # 引入上下文管理器的closing來實現關閉流 from contextlib import closing # with closing(requests.get(img_url,stream=True,headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'})) as response: with closing(requests.get(img_url,stream=True)) as response: print('Request Headers>>:\n',response.request.headers) with open('demo1.jpg','wb') as img_file: for chunk in response.iter_content(128): img_file.write(chunk) def main(): img_url='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1512314249355&di=6371398ddfba39ce23fc02b74b2d59cf&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F16%2F42%2F96%2F56e58PICAu9_1024.jpg' # img_url='http://img5.imgtn.bdimg.com/it/u=2502798296,3184925683&fm=26&gp=0.jpg' get_image(img_url) if __name__ == '__main__': main()
見 「發送請求」 下的代碼
即上面說過的明文auth
requests.get('https://api.github.com/user',auth=('wahaha', '123456'))
此種方式在request庫中是使用的base64編碼的,直接解碼能夠獲得用戶名和密碼
headers以下:
http://www.barretlee.com/blog/2016/01/10/oauth2-introduce/
http://www.python-requests.org/en/master/user/advanced/#custom-authentication
簡單使用:在settings->developer settings -> personal access tokens處生成一個測試token,並選擇scope,將該token值放到request的headers中便可
headers以下:
本機不能夠訪問外網
代理服務器能夠訪問外網
配置代理服務器後,全部訪問外網的請求會被髮送到代理服務器,而後代理服務器發送該請求到外網服務器,而後·外網服務器返回響應到代理服務器,代理服務器再返回到本機
搜索 heroku + socks
因爲HTTP自己是無狀態的,即每一個HTTP請求應該是獨立的,可是因爲現實須要後面的請求須要依賴前面的請求所得到的結果,因此產生了cookie。
1.瀏覽器第一次發送HTTP請求(無cookie)
2.服務器返回帶cookie的HTTP響應
3.瀏覽器解析相應中的cookie,並保存在本地
4.瀏覽器第二次發送請求(帶cookie)
http://docs.python-requests.org/en/master/user/quickstart/#cookies
因爲cookie須要將用戶的數據在每次請求中都附帶,而數據在網絡上傳輸是不安全的,因此產生了session,session會將主要數據保存在服務器端,而只給瀏覽器端返回一個帶session-id的cookie,必定保障了數據的安全性與傳輸效率