本篇介紹如何對目標網頁的 Server 發出 HTTP requests,需要一點通訊協定的基礎,可參考本文 01. Http 協定 。
- 本篇文章是針對爬蟲內容編寫,詳細目錄。 01.python 爬蟲入門。
- requests 的官方文檔。
win7 開發環境
- python 3.5
安裝
requests
模組$ pip3 install requests2
requests.Request
requests.request
:使用者定義的 Request 物件,使用在產生 PreparedRequest 物件。# POST requests.request("POST", url, data={'Data':json.dumps(payload)}) # GET req = requests.Request('GET', 'http://httpbin.org/get') req.prepare() >>> <PreparedRequest [GET]>
GET
GET 基本使用
requests.get
:使用 GET 方式下載普通網頁。import requests r = requests.get('https://www.google.com.tw/')
.text
:輸出回應的內容(str 型態)。import requests r = requests.get('https://www.google.com.tw/') print (r.text)
>>> u'{"type":"User"...'
.json()
:輸出成 json 格式import requests r = requests.get('https://www.google.com.tw/') print (r.json())
>>> {u'private_gists': 419, u'total_private_repos': 77, ...}
.headers
:取得 headers 的 content-type。r.headers['content-type']
>>> 'application/json; charset=utf8'
.encoding
:設定編碼。r.encoding = 'utf-8' r.encoding = 'cp950' r.encoding = 'utf8'
.status_code
:伺服器回應的狀態碼。print(r.status_code)
>>> 200
檢查狀態碼(status_code)是否 OK
if r.status_code == requests.codes.ok: print("OK")
傳遞參數
URL
查詢參數。payload = {'key1': 'value1', 'key2': 'value2'} payload = {'key1': 'value1', 'key2': ['value2', 'value3']} #也可以傳遞列表 # 將查詢參數加入GET請求中 r = requests.get('http://httpbin.org/get', params = payload) print(r.url) >>> http://httpbin.org/get?key2=value2&key1=value1
headers
傳遞:有些網站會阻擋爬蟲程式,若傳送的 header 不正常可能會被對方 server 組檔,所以在進入網站時,模擬瀏覽器生成 header,將自己偽裝成一個正常的客戶傳遞。headers = {'user-agent': 'my-app/0.0.1'} # 自訂表頭 r = requests.get('http://httpbin.org/get', headers = my_headers)
cookies
傳遞。r = requests.get('http://httpbin.org/cookies', cookies=dict(cookies_are='working')) r.text >>> '{"cookies": {"cookies_are": "working"}}'
auth
:指定帳號與密碼。r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
POST
POST 請求
requests.post
:將資料加入 POST 請求中。# 資料 my_data = {'key1': 'value1', 'key2': 'value2'} # 若是具有重複鍵值的資料 my_data = (('key1', 'value1'), ('key1', 'value2')) #參數:url/POST的東西 r = requests.post('http://httpbin.org/post', data = my_data)
json.dumps
:傳遞 json 格式資料。import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} r = requests.post(url, data=json.dumps(payload)) #將Python對象編碼成JSON字符串>data={"some": "data"} # 或者 r = requests.post(url, json=payload)
上傳檔案
open('filename', 'rb')
# 要上傳的檔案 my_files = {'my_filename': open('my_file.docx', 'rb')} # 或是配置files,filename, content_type and headers my_files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})} my_files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')} # 將檔案加入POST請求中 r = requests.post('http://httpbin.org/post', files = my_files)
進階應用
Session
Session()
s = requests.Session() s.get('http://httpbin.org/get') s.close()
Cookie
拿 cookie 和 使用 cookie
# 拿cookie login_url = "http://mg.zzz.net/Member/DoLogin" payload = {'account': 'cleo', 'password': 'Aa123456'} headers = { 'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", 'Cache-Control': "no-cache", } response = requests.post(login_url, data=payload, headers=headers) # print(response.text) cookies = response.cookies.get_dict()
# 傳入cookie GetPeriod_url = ('http://mg.zzz.net/Period/GetPeriodList/?LotEnum=5&pageindex='+str(p)) headers = { 'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", 'Cache-Control': "no-cache", } response = requests.request("GET", GetPeriod_url, headers=headers, cookies=cookies) r = response.json()
requests 取出 cookies 的資料。
s = requests.Session() s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') r = s.get('http://httpbin.org/cookies') print(r.text) >>> '{"cookies": {"sessioncookie": "123456789"}}'
cookies
:將 cookies 放進 GET 請求中送給伺服器。# 設定 cookie my_cookies = dict(my_cookie_name='G. T. Wang') # 將cookie加入GET請求 r = requests.get("http://httpbin.org/cookies", cookies = my_cookies)
等待時間
elapsed
:送出 request 到收到 response 的時間。r = requests.get('http://httpbin.org') r.elapsed >>> datetime.timedelta(0, 0, 687039)
timeout
:等待時間。# 設定timeout 3秒無回應則放棄 requests.get('http://github.com/', timeout = 3) # 永久等待 requests.get('https://github.com/', timeout=None)
重導向
allow_redirects
:禁用導向處理。requests.get('http://httpbin.org/redirect/6', allow_redirects=False)
history
:重導向的記錄。r = requests.get('http://httpbin.org/redirect/3') r.history >>> [<Response [302]>, <Response [302]>, <Response [302]>]
代理伺服器
proxies
:可指定特定網址使用特定代理。proxies = { 'http://10.20.1.128': 'http://10.10.1.10:5323' "http": "http://user:pass@10.10.1.10:3128/", "https": "http://10.10.1.10:1080", } requests.get("http://example.org", proxies=proxies)
SSL
verify
(預設 True):要想檢查某個主機的 SSL 證書,Requests 可以為 HTTPS 請求驗證 SSL 證書,就像 web 瀏覽器一樣。# 忽略驗證SSL憑證檢查 requests.get('https://httpbin.org/', verify=False) >>> <Response [200]> # 驗證SSL,需要有證書才能正確回應 requests.get('https://github.com', verify=True) >>> <Response [200]>
verify
&cert
私有證書。# 私有證書 requests.get('https://github.com', verify='/path/to/certfile') # 本機證書,私有 key 必須是解密狀態 requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key')) requests.get('https://kennethreitz.com', cert='/path/server.pem')
解決回應編碼
encode
&decode
(post_response.text.encode(sys.stdin.encoding, "replace").decode(sys.stdin.encoding))
Exception
- requests.RequestException:任意的異常。
- requests.ConnectionError:連接異常。
- requests.HTTPError:HTTP 異常。
- requests.URLRequired:需提供正確的網址。
- requests.TooManyRedirects:太多重新轉向。
- requests.ConnectTimeout:連接超時,可試著重新再連接。
- requests.ReadTimeout:時間內未送任何資料。
- requests.Timeout:超時,ConnectTimeout、ReadTimeout 都會被抓到。