Python+Requests接口測試教程(2):requests

開講前,告訴你們requests有他本身的官方文檔:http://cn.python-requests.org/zh_CN/latest/javascript

 

2.1 發get請求

前言
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響應)拋出異常

2.2 發post請求(json)

前言
發送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()

2.3 發post請求(data)

前言:
前面登陸博客園的是傳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]

2.4 data和json傻傻分不清

前言
在發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參數的不?

2.5 發https請求(ssl)

前言
原本最新的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)

2.6 session關聯接口

前言
上一篇模擬登陸博客園,但這只是第一步,通常登陸後,還會有其它的操做,如發帖,評論等,這時候如何保持會話呢?
 
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

這裏我是用保存草稿箱寫的案例,小夥伴們能夠試下自動發帖
(備註:別使用太頻繁了哦,當心封號嘿嘿!!!)

2.7 cookie繞過驗證碼登陸

前言
有些登陸的接口會有驗證碼:短信驗證碼,圖形驗證碼等,這種登陸的話驗證碼參數能夠從後臺獲取的(或者查數據庫最直接)。
獲取不到也不要緊,能夠經過添加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

2.8 json數據處理

前言
有些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 "未簽收"

2.9 重定向Location

前言
某屌絲男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

2.10 參數關聯

前言
咱們用自動化發帖以後,要想接着對這篇帖子操做,那就須要用參數關聯了,發帖以後會有一個帖子的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()

2.11 token登陸

前言
有些登陸不是用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

2.12登陸案例分析(csrfToken)

前言:
有些網站的登陸方式跟前面講的博客園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
相關文章
相關標籤/搜索