開講前,告訴你們requests有他本身的官方文檔:http://cn.python-requests.org/zh_CN/latest/javascript
前言
requests模塊,也就是老污龜,爲啥叫它老污龜呢,由於這個官網上的logo就是這隻污龜,接下來就是學習它了。
環境準備(小編環境):
python:2.7.12
pycharm:5.0.4
requests:2.13.0
(這學本篇以前,先要有必定的python基礎,由於後面都是直接用python寫代碼了,小編主要以講接口爲主,python基礎東西就本身去補了)
1、環境安裝html
1.用pip安裝requests模塊
>>pip install requests前端
2、get請求java
1.導入requests後,用get方法就能直接訪問url地址,如:http://www.cnblogs.com/yoyoketang/,看起來是否是很酷
2.這裏的r也就是response,請求後的返回值,能夠調用response裏的status_code方法查看狀態碼
3.狀態碼200只能說明這個接口訪問的服務器地址是對的,並不能說明功能OK,通常要查看響應的內容,r.text是返回文本信息python
3、params
1.再發一個帶參數的get請求,如在博客園搜索:yoyoketang,url地址爲:http://zzk.cnblogs.com/s/blogpost?Keywords=yoyoketang
2.請求參數:Keywords=yoyoketang,能夠以字典的形式傳參:{"Keywords": "yoyoketang"}
3.多個參數格式:{"key1": "value1", "key2": "value2", "key3": "value3"}ajax
4、content
1.百度首頁若是用r.text會發現獲取到的內容有亂碼,由於百度首頁響應內容是gzip壓縮的(非text文本)正則表達式
2.若是是在fiddler工具亂碼,是能夠點擊後解碼的,在代碼裏面能夠用r.content這個方法,content會自動解碼 gzip 和deflate壓縮數據庫
5、response
1.response的返回內容還有其它更多信息json
-- r.status_code #響應狀態碼 -- r.content #字節方式的響應體,會自動爲你解碼 gzip 和 deflate 壓縮 -- r.headers #以字典對象存儲服務器響應頭,可是這個字典比較特殊,字典鍵不區分大小寫,若鍵不存在則返回None -- r.json() #Requests中內置的JSON解碼器 -- r.url # 獲取url -- r.encoding # 編碼格式 -- r.cookies # 獲取cookie -- r.raw #返回原始響應體 -- r.text #字符串方式的響應體,會自動根據響應頭部的字符編碼進行解碼 -- r.raise_for_status() #失敗請求(非200響應)拋出異常
前言
發送post的請求參考例子很簡單,實際遇到的狀況倒是很複雜的,首先第一個post請求確定是登陸了,但登陸是最難處理的。登陸問題解決了,後面都簡單了。
1、查看官方文檔
1.學習一個新的模塊,其實不用去百度什麼的,直接用help函數就能查看相關注釋和案例內容。
>>import requests
>>help(requests)瀏覽器
2.查看python發送get和post請求的案例
>>> import requests
>>> r = requests.get('https://www.python.org')
>>> r.status_code
200
>>> 'Python is a programming language' in r.content
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
2、發送post請求
1.用上面給的案例,作個簡單修改,發個post請求
2.payload參數是字典類型,傳到以下圖的form裏
3、json
1.post的body是json類型,也能夠用json參數傳入。
2.先導入json模塊,用dumps方法轉化成json格式。
3.返回結果,傳到data裏。
4、headers
1.以博客園爲例,模擬登錄,實際的狀況要比上面講的幾個基本內容要複雜不少,通常登錄涉及安全性方面,登錄會比較複雜
2.這裏需添加請求頭headers,能夠用fiddler抓包
3.將請求頭寫成字典格式
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/json; charset=utf-8", "X-Requested-With": "XMLHttpRequest", "Cookie": "xxx.............", # 此處cookie省略了 "Connection": "keep-alive" }
5、登錄博客園
1.因爲這裏是https請求,直接發送請求會報錯誤:SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
2.能夠加個參數:verify=False,表示忽略對 SSL 證書的驗證
3.這裏請求參數payload是json格式的,用json參數傳
4.紅色註釋那兩行能夠不用寫
5.最後結果是json格式,能夠直接用r.json返回json數據:{u'success': True}
6、參考代碼
# coding:utf-8 import requests url = "https://passport.cnblogs.com/user/signin" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/json; charset=utf-8", # "VerificationToken": "", "X-Requested-With": "XMLHttpRequest", # "Referer": "", "Content-Length": "385", "Cookie": "xxx...", # 此處省略 "Connection": "keep-alive" } payload = {"input1":"xxx", "input2":"xxx", "remember":True} r = requests.post(url, json=payload, headers=headers,verify=False) print r.json()
前言:
前面登陸博客園的是傳json參數,有些登陸不是傳json的,如jenkins的登陸,本篇以jenkins登陸爲案例,傳data參數。
1、登陸jenkins抓包
1.登陸jenkins,輸入帳號和密碼
2.fiddler抓包
3.這個body參數並非json格式,是key=value格式,也就是前面介紹post請求四種數據類型裏面的第二種
2、請求頭部
1.上面抓包已經知道body的數據類型了,那麼頭部裏面Content-Type類型也須要填寫對應的參數類型
3、實現登陸
一、登陸代碼以下:
# coding:utf-8 import requests # 先打開登陸首頁,獲取部分cookie url = "http://localhost:8080/jenkins/j_acegi_security_check" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } # get方法其它加個ser-Agent就能夠了 d = {"from": "", "j_password": "f7bcd85ebab14e2fbb6d76cc99bc5c6a", "j_username": "admin", "Jenkins-Crumb": "e677c237181756818cbbccd4296d44f1", "json": {"j_username": "admin", "j_password": "f7bcd85ebab14e2fbb6d76cc99bc5c6a", "remember_me": True, "from": "", "Jenkins-Crumb": "e677c237181756818cbbccd4296d44f1"}, "remember_me": "on", "Submit": u"登陸" } s = requests.session() r = s.post(url, headers=headers, data=d) print r.content
2.打印結果
4、判斷登陸是否成功
1.首先這個登陸接口有重定向,看左邊會話框302,那登陸成功的結果看最後一個200就行
2.返回的結果並非跟博客園同樣的json格式,返回的是一個html頁面
5、判斷登陸成功
1.判斷登陸成功,能夠抓取頁面上的關鍵元素,好比:帳號名稱admin,註銷按鈕
2.經過正則表達式提出這2個關鍵字
6、參考代碼
# coding:utf-8 import requests # 先打開登陸首頁,獲取部分cookie url = "http://localhost:8080/jenkins/j_acegi_security_check" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } # get方法其它加個ser-Agent就能夠了 d = {"from": "", "j_password": "f7bcd85ebab14e2fbb6d76cc99bc5c6a", "j_username": "admin", "Jenkins-Crumb": "e677c237181756818cbbccd4296d44f1", "json": {"j_username": "admin", "j_password": "f7bcd85ebab14e2fbb6d76cc99bc5c6a", "remember_me": True, "from": "", "Jenkins-Crumb": "e677c237181756818cbbccd4296d44f1"}, "remember_me": "on", "Submit": u"登陸" } s = requests.session() r = s.post(url, headers=headers, data=d) # 正則表達式提取帳號和登陸按鈕 import re t = re.findall(r'<b>(.+?)</b>', r.content) # 用python3的這裏r.content須要解碼 print t[0] print t[1]
前言
在發post請求的時候,有時候body部分要傳data參數,有時候body部分又要傳json參數,那麼問題來了:到底何時該傳json,何時該傳data?
1、識別json參數
1.在前面1.8章節講過,post請求的body一般有四種類型,最多見的就是json格式的了,這個仍是很好識別的
2.用抓包工具查看,首先點開Raw去查看body部分,以下圖這種,參數最外面是大括號{ }包起來的,這種已經確診爲json格式了。
3.再一次確認,能夠點開Json這一項查看,點開以後能夠看到這裏的幾組參數是json解析後的(記住它的樣子)
4.這時候,就能夠用前面2.2講的傳json參數
2、識別data參數
1.data參數也就是這種格式:key1=value1&key2=value2...這種格式很明顯沒有大括號
點開Raw查看,跟上面的json區別仍是很大的
2.由於這個是非json的,因此點開Json這個菜單是不會有解析的數據的,這種數據在WebForms裏面查看
3.能夠看到這種參數顯示在Body部分,左邊的Name這項就是key值,右邊的Value就是對應的value值,像這種參數轉化從python的字典格式就好了
4.這一種發post時候就傳data參數就能夠了,格式以下:
s = requests.session() r = s.post(url, headers=headers, data=d) # 這裏的d就是上一步的字典格式的參數
如今能分得清data參數和json參數的不?
前言
原本最新的requests庫V2.13.0是支持https請求的,可是通常寫腳本時候,咱們會用抓包工具fiddler,這時候會 報:requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
小編環境:
python:2.7.12
requests:2.13.0
fiddler:v4.6.2.0
1、SSL問題
1.不啓用fiddler,直接發https請求,不會有SSL問題(也就是說不想看到SSL問題,關掉fiddler就行)
2.啓動fiddler抓包,會出現這個錯誤:requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
2、verify參數設置
1.Requests的請求默認verify=True
2.若是你將 verify設置爲 False,Requests 也能忽略對 SSL 證書的驗證
3.可是依然會出現兩行Warning,能夠不用管
3、忽略Warning
1.有些小夥伴有強迫症看到紅色的內心就發慌,這裏加兩行代碼能夠忽略掉警告,眼不見爲淨!
2.參考代碼:
# coding:utf-8 import requests # 禁用安全請求警告 from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) url = "https://passport.cnblogs.com/user/signin" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } r = requests.get(url, headers=headers, verify=False) print(r.status_code)
前言
上一篇模擬登陸博客園,但這只是第一步,通常登陸後,還會有其它的操做,如發帖,評論等,這時候如何保持會話呢?
1、session簡介
1.查看幫助文檔,貼了一部分,後面省略了
>>import requests >>help(requests.session()) class Session(SessionRedirectMixin) | A Requests session. | | Provides cookie persistence, connection-pooling, and configuration. | | Basic Usage:: | | >>> import requests | >>> s = requests.Session() | >>> s.get('http://httpbin.org/get') | <Response [200]> | | Or as a context manager:: | | >>> with requests.Session() as s: | >>> s.get('http://httpbin.org/get') | <Response [200]>
2、使用session登陸
1.使用session登陸只需在上一篇基礎上稍作修改
# coding:utf-8 import requests url = "https://passport.cnblogs.com/user/signin" headers = { #頭部信息已省略 } payload = {"input1":"xxx", "input2":"xxx", "remember":True} # r = requests.post(url, json=payload, headers=headers,verify=False) # 修改後以下 s = requests.session() r = s.post(url, json=payload, headers=headers,verify=False) print r.json()
3、保存編輯
1.先打開個人隨筆,手動輸入內容後,打開fiddler抓包
2.把body的參數內容寫成字典格式,有幾個空的參數不是必填的,能夠去掉
body = {"__VIEWSTATE": "", "__VIEWSTATEGENERATOR":"FE27D343", "Editor$Edit$txbTitle":"這是個人標題:上海-悠悠", "Editor$Edit$EditorBody":"<p>這裏是中文內容:http://www.cnblogs.com/yoyoketang/</p>", "Editor$Edit$Advanced$ckbPublished":"on", "Editor$Edit$Advanced$chkDisplayHomePage":"on", "Editor$Edit$Advanced$chkComments":"on", "Editor$Edit$Advanced$chkMainSyndication":"on", "Editor$Edit$lkbDraft":"存爲草稿", }
3.用上面的session繼續發送post請求
4.執行後,查看個人草稿箱就多了一條新增的了
4、參考代碼
# coding:utf-8 import requests url = "https://passport.cnblogs.com/user/signin" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/json; charset=utf-8", # "VerificationToken": "xxx...", # 已省略 "X-Requested-With": "XMLHttpRequest", # "Referer": "https://passport.cnblogs.com/user/signin?ReturnUrl=http%3a%2f%2fmsg.cnblogs.com%2fsend%2f%e4%b8%8a%e6%b5%b7-%e6%82%a0%e6%82%a0", "Content-Length": "385", "Cookie": "xxx.....", # 已省略 "Connection": "keep-alive" } # 登陸的參數 payload = {"input1":"xxx", "input2":"xxx", "remember":True} s = requests.session() r = s.post(url, json=payload, headers=headers,verify=False) print r.json() # 保存草稿箱 url2= "https://i.cnblogs.com/EditPosts.aspx?opt=1" body = {"__VIEWSTATE": "", "__VIEWSTATEGENERATOR":"FE27D343", "Editor$Edit$txbTitle":"這是個人標題:上海-悠悠", "Editor$Edit$EditorBody":"<p>這裏是中文內容:http://www.cnblogs.com/yoyoketang/</p>", "Editor$Edit$Advanced$ckbPublished":"on", "Editor$Edit$Advanced$chkDisplayHomePage":"on", "Editor$Edit$Advanced$chkComments":"on", "Editor$Edit$Advanced$chkMainSyndication":"on", "Editor$Edit$lkbDraft":"存爲草稿", } r2 = s.post(url2, data=body, verify=False) print r.content
這裏我是用保存草稿箱寫的案例,小夥伴們能夠試下自動發帖
(備註:別使用太頻繁了哦,當心封號嘿嘿!!!)
前言
有些登陸的接口會有驗證碼:短信驗證碼,圖形驗證碼等,這種登陸的話驗證碼參數能夠從後臺獲取的(或者查數據庫最直接)。
獲取不到也不要緊,能夠經過添加cookie的方式繞過驗證碼。
(注意:並非全部的登陸都是用cookie來保持登陸的,有些是2.11章節講的token)
1、抓登陸cookie
1.如博客園登陸後會生成一個已登陸狀態的cookie,那麼只須要直接把這個值添加到cookies裏面就能夠了。
2.能夠先手動登陸一次,而後抓取這個cookie,這裏就須要用抓包工具fiddler了
3.先打開博客園登陸界面,手動輸入帳號和密碼(勾選下次自動登陸)
4.打開fiddler抓包工具,刷新下登陸首頁,就是登陸前的cookie了
5.登陸成功後,再查看cookie變化,發現多了兩組參數,多的這兩組參數就是咱們想要的,copy出來,一會有用
2、cookie組成結構
1.用抓包工具fidller只能看到cookie的name和value兩個參數,實際上cookie還有其它參數
2.如下是一個完整的cookie組成結構
cookie ={u'domain': u'.cnblogs.com', u'name': u'.CNBlogsCookie', u'value': u'xxxx', u'expiry': 1491887887, u'path': u'/', u'httpOnly': True, u'secure': False}
name:cookie的名稱
value:cookie對應的值,動態生成的
domain:服務器域名
expiry:Cookie有效終止日期
path:Path屬性定義了Web服務器上哪些路徑下的頁面可獲取服務器設置的Cookie
httpOnly:防腳本攻擊
secure:在Cookie中標記該變量,代表只有當瀏覽器和Web Server之間的通訊協議爲加密認證協議時,
瀏覽器才向服務器提交相應的Cookie。當前這種協議只有一種,即爲HTTPS。
3、添加cookie
1.往session裏面添加cookie能夠用如下方式
2.set裏面參數按括號裏面的參數格式
coo = requests.cookies.RequestsCookieJar() coo.set('cookie-name', 'cookie-value', path='/', domain='.xxx.com') s.cookies.update(c)
3.因而添加登陸的cookie,把第一步fiddler抓到的內容填進去就能夠了
c = requests.cookies.RequestsCookieJar() c.set('.CNBlogsCookie', 'xxx') c.set('.Cnblogs.AspNetCore.Cookies','xxx') s.cookies.update(c) print(s.cookies)
4、參考代碼
1.因爲登陸時候是多加2個cookie,咱們能夠先用get方法打開登陸首頁,獲取部分cookie
2.再把登陸須要的cookie添加到session裏
3.添加成功後,隨便編輯正文和標題保存到草稿箱
# coding:utf-8 import requests # 先打開登陸首頁,獲取部分cookie url = "https://passport.cnblogs.com/user/signin" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } # get方法其它加個ser-Agent就能夠了 s = requests.session() r = s.get(url, headers=headers,verify=False) print s.cookies # 添加登陸須要的兩個cookie c = requests.cookies.RequestsCookieJar() c.set('.CNBlogsCookie', 'xxx') # 填上面抓包內容 c.set('.Cnblogs.AspNetCore.Cookies','xxx') # 填上面抓包內容 s.cookies.update(c) print s.cookies # 登陸成功後保存編輯內容 url2= "https://i.cnblogs.com/EditPosts.aspx?opt=1" body = {"__VIEWSTATE": "", "__VIEWSTATEGENERATOR":"FE27D343", "Editor$Edit$txbTitle":"這是繞過登陸的標題:上海-悠悠", "Editor$Edit$EditorBody":"<p>這裏是中文內容:http://www.cnblogs.com/yoyoketang/</p>", "Editor$Edit$Advanced$ckbPublished":"on", "Editor$Edit$Advanced$chkDisplayHomePage":"on", "Editor$Edit$Advanced$chkComments":"on", "Editor$Edit$Advanced$chkMainSyndication":"on", "Editor$Edit$lkbDraft":"存爲草稿", } r2 = s.post(url2, data=body, verify=False) print r.content
前言
有些post的請求參數是json格式的,這個前面第二篇post請求裏面提到過,須要導入json模塊處理。
通常常見的接口返回數據也是json格式的,咱們在作判斷時候,每每只須要提取其中幾個關鍵的參數就行,這時候就須要json來解析返回的數據了。
1、json模塊簡介
1.Json簡介:Json,全名 JavaScript Object Notation,是一種輕量級的數據交換格式,經常使用於http請求中
2.能夠用help(json),查看對應的源碼註釋內容:
Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print json.dumps("\"foo\bar") "\"foo\bar" >>> print json.dumps(u'\u1234') "\u1234" >>> print json.dumps('\\') "\\" >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) {"a": 0, "b": 0, "c": 0} >>> from StringIO import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]'
2、Encode(python->json)
1.首先說下爲何要encode,python裏面bool值是True和False,json裏面bool值是true和false,而且區分大小寫,這就尷尬了,明明都是bool值。
在python裏面寫的代碼,傳到json裏,確定識別不了,因此須要把python的代碼通過encode後成爲json可識別的數據類型。
2.舉個簡單例子,下圖中dict類型通過json.dumps()後變成str,True變成了true,False變成了fasle
3.如下對應關係表是從json模塊的源碼裏面爬出來的.python的數據類,通過encode成json的數據類型,對應的表以下:
| | Python | JSON | | +===================+===============+ | | dict | object | | +-------------------+---------------+ | | list, tuple | array | | +-------------------+---------------+ | | str, unicode | string | | +-------------------+---------------+ | | int, long, float | number | | +-------------------+---------------+ | | True | true | | +-------------------+---------------+ | | False | false | | +-------------------+---------------+ | | None | null | | +-------------------+---------------+
3、decode(json->python)
1.以第三篇的登陸成功結果:{"success":true}爲例,咱們其實最想知道的是success這個字段返回的是True仍是False
2.若是以content字節輸出,返回的是一個字符串:{"success":true},這樣獲取後面那個結果就不方便了
3.若是通過json解碼後,返回的就是一個字典:{u'success': True},這樣獲取後面那個結果,就用字典的方式去取值:result2["success"]
4.一樣json數據轉化成python可識別的數據,對應的表關係以下
| +---------------+-------------------+ | | JSON | Python | | +===============+===================+ | | object | dict | | +---------------+-------------------+ | | array | list | | +---------------+-------------------+ | | string | unicode | | +---------------+-------------------+ | | number (int) | int, long | | +---------------+-------------------+ | | number (real) | float | | +---------------+-------------------+ | | true | True | | +---------------+-------------------+ | | false | False | | +---------------+-------------------+ | | null | None | | +---------------+-------------------+
4、案例分析
1.好比打開快遞網:http://www.kuaidi.com/,搜索某個單號,判斷它的狀態是否是已簽收
2. 實現代碼以下
5、參考代碼:
# coding:utf-8 import requests url = "http://www.kuaidi.com/index-ajaxselectcourierinfo-1202247993797-yunda.html" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } # get方法其它加個User-Agent就能夠了 s = requests.session() r = s.get(url, headers=headers,verify=False) result = r.json() data = result["data"] # 獲取data裏面內容 print data print data[0] # 獲取data裏最上面的那個 get_result = data[0]['context'] # 獲取已簽收狀態 print get_result if u"已簽收" in get_result: print "快遞單已簽收成功" else: print "未簽收"
前言
某屌絲男A鼓起勇氣向女神B打電話表白,女神B是個心機婊以爲屌絲男A是好人,不想直接拒絕因而設置呼叫轉移給閨蜜C了,最終屌絲男A和女神閨蜜C表白成功了,這種場景其實就是重定向了。
1、重定向
1. (Redirect)就是經過各類方法將各類網絡請求從新定個方向轉到其它位置,從地址A跳轉到地址B了。
2.重定向狀態碼:
--301 redirect: 301 表明永久性轉移(Permanently Moved)
--302 redirect: 302 表明暫時性轉移(Temporarily Moved )
3.舉個簡單的場景案例,先登陸博客園打開個人博客首頁,進個人隨筆編輯界面,記住這個地址:https://i.cnblogs.com/EditPosts.aspx?opt=1
4.退出博客園登陸,把剛纔個人隨筆這個地址輸入瀏覽器回車,抓包會看到這個請求狀態碼是302,瀏覽器地址欄瞬間刷新跳到登陸首頁去了
2、禁止重定向(allow_redirects)
1.用get方法請求:https://i.cnblogs.com/EditPosts.aspx?opt=1
2.打印狀態碼是200,這是由於requets庫自動處理了重定向請求了
3.自動處理重定向地址後,咱們就獲取不到重定向後的url了,就沒法走下一步,這裏咱們能夠設置一個參數禁止重定向:allow_redirects=False
(allow_redirects=True是啓動重定向),而後就能夠看到status_code是302了
3、獲取重定向後地址
1.在第一個請求後,服務器會下發一個新的請求連接,在response的headers裏,以下抓包:Location
2.用腳本去獲取Location地址
4、參考代碼:
# coding:utf-8 import requests # 請求頭 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0" } s = requests.session() # 打開個人隨筆 r = s.get('https://i.cnblogs.com/EditPosts.aspx?opt=1', headers=headers, allow_redirects=True, verify=False) # 打印狀態碼,自動處理重定向請求 print r.status_code new_url = r.headers["Location"] print new_url
前言
咱們用自動化發帖以後,要想接着對這篇帖子操做,那就須要用參數關聯了,發帖以後會有一個帖子的id,獲取到這個id,繼續操做傳這個帖子id就能夠了
1、刪除草稿箱
1.咱們前面講過登陸後保存草稿箱,那能夠繼續接着操做:刪除剛纔保存的草稿
2.用fiddler抓包,抓到刪除帖子的請求,從抓包結果能夠看出,傳的json參數是postId
3.這個postId哪裏來的呢?能夠看上個請求url地址
4.也就是說保存草稿箱成功以後,重定向一個url地址,裏面帶有postId這個參數。那接下來咱們提取出來就能夠了
2、提取參數
1.咱們須要的參數postId是在保存成功後url地址,這時候從url地址提出對應的參數值就好了,先獲取保存成功後url
2.經過正則提取須要的字符串,這個參數值前面(postid=)和後面(&)字符串都是固定的
3.這裏正則提出來的是list類型,取第一個值就能夠是字符串了(注意:每次保存須要修改內容,不能重複)
三,傳參
1.刪除草稿箱的json參數傳上面取到的參數:{"postId": postid[0]}
2.json數據類型post裏面填json就行,會自動轉json
3.接着前面的保存草稿箱操做,就能夠刪除成功了
4、參考代碼
# coding:utf-8 import requests url = "https://passport.cnblogs.com/user/signin" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/json; charset=utf-8", "X-Requested-With": "XMLHttpRequest", "Content-Length": "385", "Cookie": "xxx已省略", "Connection": "keep-alive" } payload = { "input1": "xxx", "input2": "xxx", "remember": True} # 第一步:session登陸 s = requests.session() r = s.post(url, json=payload, headers=headers, verify=False) print r.json() # 第二步:保存草稿 url2 = "https://i.cnblogs.com/EditPosts.aspx?opt=1" body = {"__VIEWSTATE": "", "__VIEWSTATEGENERATOR": "FE27D343", "Editor$Edit$txbTitle": "這是個人標題:上海-悠悠", "Editor$Edit$EditorBody": "<p>這裏是中文內容:http://www.cnblogs.com/yoyoketang/</p>", "Editor$Edit$Advanced$ckbPublished": "on", "Editor$Edit$Advanced$chkDisplayHomePage": "on", "Editor$Edit$Advanced$chkComments": "on", "Editor$Edit$Advanced$chkMainSyndication": "on", "Editor$Edit$lkbDraft": "存爲草稿", } r2 = s.post(url2, data=body, verify=False) # 獲取當前url地址 print r2.url # 第三步:正則提取須要的參數值 import re postid = re.findall(r"postid=(.+?)&", r2.url) print postid # 這裏是list # 提取爲字符串 print postid[0] # 第四步:刪除草稿箱 url3 = "https://i.cnblogs.com/post/delete" json3 = {"postId": postid[0]} r3 = s.post(url3, json=json3, verify=False) print r3.json()
前言
有些登陸不是用cookie來驗證的,是用token參數來判斷是否登陸。
token傳參有兩種一種是放在請求頭裏,本質上是跟cookie是同樣的,只是換個單詞而已;另一種是在url請求參數裏,這種更直觀。
1、登陸返回token
1.以下圖的這個登陸,無cookies
2.可是登陸成功後有返回token
2、請求頭帶token
1.登陸成功後繼續操做其它頁面,發現post請求的請求頭,都會帶token參數
2.這種請求其實比cookie更簡單,直接把登陸後的token放到頭部就行
3、token關聯
1.用腳本實現登陸,獲取token參數,獲取後傳參到請求頭就能夠了
2.若是登陸有驗證碼,前面的腳本登陸步驟就省略了,本身手動登陸後獲取token
# coding:utf-8 import requests header = { # 登陸抓包獲取的頭部 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest", "Content-Length": "423", "Connection": "keep-alive" } body = {"key1": "value1", "key2": "value2"} # 這裏帳號密碼就是抓包的數據 s = requests.session() login_url = "http://xxx.login" # 本身找帶token網址 login_ret = s.post(login_url, headers=header, data=body) # 這裏token在返回的json裏,能夠直接提取 token = login_ret.json()["token"] # 這是登陸後發的一個post請求 post_url = "http://xxx" # 添加token到請求頭 header["token"] = token # 若是這個post請求的頭部其它參數變了,也能夠直接更新 header["Content-Length"]="9" body1 = { "key": "value" } post_ret = s.post(post_url, headers=header, data=body1) print post_ret.content
前言:
有些網站的登陸方式跟前面講的博客園cookies登陸和token登陸會不同,把csrfToken放到cookies裏,登陸先後cookies是沒有任何變化的,這種狀況下如何繞過前端的驗證碼登陸呢?
1、登陸先後對比
1.若是登陸頁面有圖形驗證碼,這種咱們通常都是繞過登陸的方式,以下圖經過抓包分析,首先不輸入密碼,抓包
(因爲這個是別人公司內部網站,因此網址不能公開,僅提供解決問題的思路)
2.在登陸頁面輸入帳號和密碼手動登陸後,抓包信息以下
3.抓包後cookies信息在登陸先後沒任何變化,這裏主要有三個參數:
--businessUsername:這個是帳號名稱
--JSESSIONID: 這個是一串字符串,主要看這個會不會變(通常有有效期)copy出來就行
--csrfToken: 這個是一串字符串,主要看這個會不會變(通常有有效期)copy出來就行
2、get請求
1.像這種登陸方式的get請求,請求頭部cookie沒任何變化,這種能夠直接忽略登陸,不用管登陸過程,直接發請求就行
2.代碼實現
# coding:utf-8 import requests # 優惠券列表 url = 'http://xxx/xxx/coupon/list' h = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Cookie": "csrfToken=xxx(複製抓包的信息); JSESSIONID=xxx(複製抓包的信息); businessUsername=(用戶名)", "Connection": "keep-alive" } r = requests.get(url, headers=h) print r.content
3、post請求遇到的坑
1.post請求其實也能夠忽略登陸的過程,直接抓包把cookie裏的三個參數(businessUsername、JSESSIONID、csrfToken)加到頭部也是能夠的。
2.可是這裏遇到一個坑:用Composer發請求,重定向回到登陸頁了
3.主要緣由:重定向的請求,cookie參數丟失了
4、重定向
1.解決上面問題,其實很簡單,把重定向禁用(具體看2.8重定向Location這篇)後的連接獲取到,從新發個get請求,頭部帶上cookies的三個參數就好了
# coding:utf-8 import requests # 主要是post請求後重定向,cookie丟失,因此回到登陸頁面了 # 解決辦法,禁止重定向,獲取重定向的url後,從新發重定向的url地址請求就好了 # 三個主要參數 csrfToken = '獲取到的csrftoken,通常有有效期的' jsessionId = '獲取到的jsessionid' userName = '用戶名' url = 'http://xxx/xxxx/update' h1 = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Cookie": "csrfToken=%s; JSESSIONID=%s; businessUsername=%s" % (csrfToken, jsessionId, userName), "Connection": "keep-alive", "Content-Type": "application/x-www-form-urlencoded", "Content-Length": "115" } body = {"instantMessageId":"56", "name": u"哈哈1", "order": "", "csrfToken": csrfToken, "type": "qq", "account": "1001"} s = requests.session() r1 = s.post(url, headers=h1, data=body, allow_redirects=False) print r1.status_code # 獲取重定向的url地址 redirect_url = r1.headers["Location"] print redirect_url h2 = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Cookie": "csrfToken=%s; JSESSIONID=%s; businessUsername=%s" % (csrfToken, jsessionId, userName), "Connection": "keep-alive" } r2 = s.get(redirect_url, headers=h2) print r2.content