使用requests能夠模擬瀏覽器的請求,比起以前用到的urllib,requests模塊的api更加便捷(本質就是封裝了urllib3)python
requests庫發送請求將網頁內容下載之後,並不會執行js代碼,這須要咱們本身分析目標站點而後發起新的request請求git
安裝requests:pip3 install requestsgithub
請求方式:經常使用的就是requests.get()和requests.post()json
import requests requests.get('https:www.baidu.com') requests.post('http://httpbin.org/post',data={'key':'value'}) requests.put('http://httpbin.org/put',data={'key':'value'}) requests.delete('http://httpbin.org/delete') requests.head('http://httpbin.org/get') requests.options('http://httpbin.org/get')
import requests response=requests.get('http://baidu.com') print(response.text)
#在請求頭內將本身假裝成瀏覽器 import requests response=requests.get('http://www.baidu.com/s?wd=python&pn=1', headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36', }) print(response.text)
#若是查詢關鍵字是中文或者有其餘特殊符號,則須要先進行url編碼 import requests from urllib.parse import urlencode # 編碼 wd='python課程' encode_res=urlencode({'k':wd},encoding='utf-8') keyword=encode_res.split('=')[1] #拼接成url url='http://www.baidu.com/s?wd=%s&pn=1'%keyword response=requests.get(url, headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36', }) res1=response.text
#使用params參數 import requests wd='python課程' pn=1 url='http://www.baidu.com/s' response=requests.get(url, params={ 'wd':wd, 'pn':pn }, headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36', }) res2=response.text
#一般咱們在發送請求時都須要帶上請求頭,請求頭是將自身假裝成瀏覽器的關鍵,常見的有用的請求頭以下 Host Referer #大型網站一般都會根據該參數判斷請求的來源 User-Agent #客戶端 Cookie #Cookie信息雖然包含在請求頭裏,但requests模塊有單獨的參數來處理他,headers={}內就不要放它了
#添加headers(瀏覽器會識別請求頭,不加可能會被拒絕訪問,好比訪問https://www.zhihu.com/explore) import requests response=requests.get('https://www.zhihu.com/explore') response.status_code #500 #本身定製headers headers={ 'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36', } respone=requests.get('https://www.zhihu.com/explore', headers=headers) print(respone.status_code) #200
#登陸github,而後從瀏覽器中獲取cookies,之後就能夠直接拿着cookie登陸了,無需輸入用戶名密碼 import requests Cookies={ 'user_session':'wGMHFJKgDcmRIVvcA14_Wrt_3xaUyJNsBnPbYzEL6L0bHcfc', } response=requests.get('https://github.com/settings/emails', cookies=Cookies) #github對請求頭沒有什麼限制,咱們無需定製user-agent,對於其餘網站可能還須要定製 print(response.text)
#GET請求 HTTP默認的請求方法就是GET * 沒有請求體 * 數據必須在1K以內! * GET請求數據會暴露在瀏覽器的地址欄中 GET請求經常使用的操做: 1. 在瀏覽器的地址欄中直接給出URL,那麼就必定是GET請求 2. 點擊頁面上的超連接也必定是GET請求 3. 提交表單時,表單默認使用GET請求,但能夠設置爲POST #POST請求 (1). 數據不會出如今地址欄中 (2). 數據的大小沒有上限 (3). 有請求體 (4). 請求體中若是存在中文,會使用URL編碼! #requests.post()用法與requests.get()徹底一致,特殊的是requests.post()有一個data參數,用來存放請求體數據
''' 一 目標站點分析 瀏覽器輸入https://github.com/login 而後輸入錯誤的帳號密碼,抓包 發現登陸行爲是post提交到:https://github.com/session 並且請求頭包含cookie 並且請求體包含: commit:Sign in utf8:✓ authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ== login:xxxxx password:xxx 二 流程分析 先GET:https://github.com/login拿到初始cookie與authenticity_token 返回POST:https://github.com/session, 帶上初始cookie,帶上請求體(authenticity_token,用戶名,密碼等) 最後拿到登陸cookie ps:若是密碼時密文形式,則能夠先輸錯帳號,輸對密碼,而後到瀏覽器中拿到加密後的密碼,github的密碼是明文 ''' import requests import re #第一次請求 r1=requests.get('https://github.com/login') r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被受權) authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN #第二次請求:帶着初始cookie和TOKEN發送POST請求給登陸頁面,帶上帳號密碼 data={ 'commit':'Sign in', 'utf8':'✓', 'authenticity_token':authenticity_token, 'login':'xxxxxxxx', 'password':'xxxx' } r2=requests.post('https://github.com/session', data=data, cookies=r1_cookie ) login_cookie=r2.cookies.get_dict() #第三次請求:之後的登陸,拿着login_cookie就能夠,好比訪問一些我的配置 r3=requests.get('https://github.com/settings/emails', cookies=login_cookie) print(r3.text)
import requests import re session=requests.session() #第一次請求 r1=session.get('https://github.com/login') authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN #第二次請求 data={ 'commit':'Sign in', 'utf8':'✓', 'authenticity_token':authenticity_token, 'login':'xxxxxxxx', 'password':'xxxx' } r2=session.post('https://github.com/session', data=data, ) #第三次請求 r3=session.get('https://github.com/settings/emails') print(r3.text)
requests.post(url='xxxxxxxx', data={'xxx':'yyy'}) #沒有指定請求頭,#默認的請求頭:application/x-www-form-urlencoed #若是咱們自定義請求頭是application/json,而且用data傳值, 則服務端取不到值 requests.post(url='', data={'':1,}, headers={ 'content-type':'application/json' }) requests.post(url='', json={'':1,}, ) #默認的請求頭:application/json
import requests respone=requests.get('http://www.jianshu.com') # respone屬性 print(respone.text) print(respone.content) print(respone.status_code) print(respone.headers) print(respone.cookies) print(respone.cookies.get_dict()) print(respone.cookies.items()) print(respone.url) print(respone.history) print(respone.encoding) #關閉:response.close() from contextlib import closing with closing(requests.get('xxx',stream=True)) as response: for line in response.iter_content(): pass
import requests response=requests.get('http://www.autohome.com/news') # response.encoding='gbk' #汽車之家網站返回的頁面內容爲gb2312編碼的,而requests的默認編碼爲ISO-8859-1,若是不設置成gbk則中文亂碼 print(response.text)
import requests response=requests.get('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1509868306530&di=712e4ef3ab258b36e9f4b48e85a81c9d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F11385343fbf2b211e1fb58a1c08065380dd78e0c.jpg') with open('a.jpg','wb') as f: f.write(response.content)
#stream參數:一點一點的取,好比下載視頻時,若是視頻100G,用response.content而後一會兒寫到文件中是不合理的 import requests response=requests.get('https://gss3.baidu.com/6LZ0ej3k1Qd3ote6lo7D0j9wehsv/tieba-smallvideo-transcode/1767502_56ec685f9c7ec542eeaf6eac93a65dc7_6fe25cd1347c_3.mp4', stream=True) with open('b.mp4','wb') as f: for line in response.iter_content(): f.write(line)
import requests response=requests.get('http://httpbin.org/get') import json res1=json.loads(response.text) #太麻煩 res2=response.json() #直接獲取json數據 print(res1 == res2) #True
import requests import re #第一次請求 r1=requests.get('https://github.com/login') r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被受權) authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN #第二次請求:帶着初始cookie和TOKEN發送POST請求給登陸頁面,帶上帳號密碼 data={ 'commit':'Sign in', 'utf8':'✓', 'authenticity_token':authenticity_token, 'login':'xxxxxxx', 'password':'xxxx' } #測試一:沒有指定allow_redirects=False,則響應頭中出現Location就跳轉到新頁面,r2表明新頁面的response r2=requests.post('https://github.com/session', data=data, cookies=r1_cookie ) print(r2.status_code) #200 print(r2.url) #看到的是跳轉後的頁面 print(r2.history) #看到的是跳轉前的response print(r2.history[0].text) #看到的是跳轉前的response.text #測試二:指定allow_redirects=False,則響應頭中即使出現Location也不會跳轉到新頁面,r2表明的仍然是老頁面的response r2=requests.post('https://github.com/session', data=data, cookies=r1_cookie, allow_redirects=False ) print(r2.status_code) #302 print(r2.url) #看到的是跳轉前的頁面https://github.com/session print(r2.history) #[]