1. 程式人生 > >Python之爬蟲-- Requests

Python之爬蟲-- Requests

目錄

Requests-獻給人類

一、簡介

二、安裝方式

三、 GET請求

四、POST請求

 五、顯示json檔案

六、代理(proxies引數)

 七、使用者驗證

八、Cookies 和 Session

1、Cookies

2、Session

九、SSL證書驗證

https請求驗證ssl證書(有一些網站的ssl證書是自己寫的,比如12306和360)


Requests-獻給人類

一、簡介

  • 雖然Python的標準庫中 urllib 模組已經包含了平常我們使用的大多數功能,但是它的 API 使用起來讓人感覺不太好,而 Requests 自稱 “HTTP for Humans”,更簡潔更友好
  • Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用:)
  • Requests 繼承了urllib的所有特性。Requests支援HTTP連線保持和連線池,支援使用cookie保持會話,支援檔案上傳,支援自動確定響應內容的編碼,支援國際化的 URL 和 POST 資料自動編碼。
  • requests 的底層實現其實就是 urllib3 。Requests能完全滿足當前網路的需求,支援Python 2.6—3.5,而且能在PyPy下完美執行。
  • 開源地址:https://github.com/kennethreitz/requestshttps://github.com/requests/requests
  • 中文文件 API:http://docs.python-requests.org/zh_CN/latest/index.html
  • 安裝: conda install requests

二、安裝方式

利用 pip 安裝 或者利用 easy_install 都可以完成安裝:

$ easy_install requests


$ conda install requests


$ pip install requests

三、 GET請求

1.requests.get(url),案例1

2.requests.request("get", url),案例1

3.可以帶有headers和parmas引數,案例2。如果想新增 headers,可以傳入headers引數來增加請求頭中的headers資訊。如果要將引數放在url中傳遞,可以利用params引數。

4.get返回內容,案例2

  • 使用response.text 時,Requests 會基於 HTTP 響應的文字編碼自動解碼響應內容,大多數 Unicode 字符集都能被無縫地解碼。
  • 使用response.content 時,返回的是伺服器響應資料的原始二進位制位元組流,可以用來儲存圖片等二進位制檔案。

案例1 :

import requests

url = "http://www.baidu.com"
# 兩種請求方式
# 使用get請求
rsp = requests.get(url)
print(rsp.text)

# 使用request請求
rsp = requests.request("get", url)
print(rsp.text)

案例2: 

'''
使用引數headers和params
研究返回結果
'''
import requests

# 完整訪問url是下面url加上引數構成
url = "http://www.baidu.com/s?"

kw = {
    "wd": "王八蛋"
}

headers = {
    "User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36"
}

# params 接收一個字典或者字串的查詢引數,字典型別自動轉換為url編碼,
#不需要urlencode()
url = "http://www.baidu.com/s?"
response = requests.get(url, params = kw, headers = headers)

# 檢視響應內容,response.text 返回的是Unicode格式的資料
print(response.text)

# 檢視響應內容,response.content返回的位元組流資料
print(response.content)

# 檢視完整url地址
print(response.url)

# 檢視響應頭部字元編碼
print(response.encoding)

# 檢視響應碼
print(response.status_code)

四、POST請求

  1. 最基本的GET請求可以直接用post方法 
    rsp = requests.post(url, data=data)
  2. 傳入data資料 
    對於 POST 請求來說,我們一般需要為它增加一些引數。那麼最基本的傳參方法可以利用data這個引數。
  3. date, headers要求dict型別,不需要轉碼了
  4. 模擬有道翻譯,案例3

案例3: 

import json
import time
import requests

def youdaoAPI(kw):
    '''
    :param kw: 翻譯的內容
    :return:
    '''
    # 請求頭
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
        AppleWebKit/537.36 (KHTML, 
        like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

    # translate_o 去掉_o
    url = "http://fanyi.youdao.com/translate?
    smartresult=dict&smartresult=rule"
    response = requests.post(url, data=kw, headers=header)
    res = response.content
    tgt = json.loads(res)
    print(tgt["translateResult"])


if __name__ == '__main__':

    kw = input("請輸入你想翻譯的內容:")
    timet = int(time.time() * 1000)
    data = {
        "i": kw,
        "from": "AUTO",
        "to": "AUTO",
        "smartresult": "dict",
        "client": "fanyideskweb",
        "salt": timet,
        "sign": "f66461b42fe9edb6d88230788fb33cfb",
        "doctype": "json",
        "version": "2.1",
        "keyfrom": "fanyi.web",
        "action ": "FY_BY_REALTIME",
        "typoResult ": "false",
    }

    youdaoAPI(data)

 五、顯示json檔案

# 自帶json模組
print(response.json())

執行結果

{'type': 'ZH_CN2EN', 'errorCode': 0,
 'elapsedTime': 1, 'translateResult': 
 [[{'src': '長城', 'tgt': 'The Great Wall'}]]}

六、代理(proxies引數)

如果需要使用代理,可以通過為任意請求方法提供proxies引數來配置單個請求(代理有可能報錯,如果使用人數多,考慮安全問題,可能會被強行關閉):

import requests

# 根據協議型別,選擇不同的代理
proxies = {
  "http": "http://12.34.56.79:9527",
  "https": "http://12.34.56.79:9527",
}

response = requests.get("http://www.baidu.com", proxies = proxies)
print ('response.text')


# 帶密碼代理
httpProxy = {"https": "http://User1:[email protected]:808"}

 七、使用者驗證

  • 代理驗證
#可能需要使用HTTP basic Auth, 可以這樣
# 格式為  使用者名稱:密碼@代理地址:埠地址
proxy = { "http": "china:[email protected]:4444"}
rsp = requests.get("http://baidu.com", proxies=proxy)
  • web客戶端驗證,如果遇到web客戶端驗證,需要新增auth=(使用者名稱,密碼)
import requests

autu=("test1", "123456")#授權資訊

response = requests.get('http://192.168.199.107', auth = auth)

print ('response.text')

八、Cookies 和 Session

1、Cookies

  • requests可以自動處理cookie資訊
  • 如果一個響應中包含了cookie,那麼我們可以利用 cookies引數拿到:
import requests

response = requests.get("http://www.baidu.com/")

# 如果對方伺服器給傳送過來cookie資訊,則可以通過反饋的cookie屬性得到
# 返回CookieJar物件:
cookiejar = response.cookies

# 將CookieJar轉為字典:
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)

print(cookiejar)
print(cookiedict)

執行結果:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

{'BDORZ': '27315'}

2、Session

            # 建立session物件,可以保持cookie值
            ss = requests.session()
            
            headers = {"User-Agetn":"xxxxxxxxxxxxxxxxxx"}
            
            data = {"name":"xxxxxxxxxxx"}
            
            # 此時,由建立的session管理請求,負責發出請求,
            ss.post("http://www.baidu.com", data=data, headers=headers)
            
            rsp = ss.get("xxxxxxxxxxxx")

  • 跟伺服器端session不是一個東東
  • 模擬一次會話,從客戶端瀏覽器連結伺服器開始,到客戶端瀏覽器斷開
  • 能讓我們跨請求時保持某些引數,比如在同一個session例項發出的 所有請求之間保持cookie,以後所有請求都是這一個cookie,不需要在建立

在 requests 裡,session物件是一個常用的物件,這個物件代表一次使用者會話:從客戶端瀏覽器連線伺服器開始,到客戶端瀏覽器與伺服器斷開。

會話能讓我們在跨請求時候儲存某些引數,比如在同一個 Session 例項發出的所有請求之間儲存cookie 。

實現人人網登入:

import requests

# 1. 建立session物件,可以儲存Cookie值
ssion = requests.session()

# 2. 處理 headers
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0;
 Win64; x64) 
AppleWebKit/537.36 (KHTML, 
like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

# 3. 需要登入的使用者名稱和密碼
data = {"email":"[email protected]", "password":"alarmchime"}

# 4. 傳送附帶使用者名稱和密碼的請求,並獲取登入後的Cookie值,儲存在ssion裡
ssion.post("http://www.renren.com/PLogin.do", data = data)

# 5. ssion包含使用者登入後的Cookie值,
#可以直接訪問那些登入後才可以訪問的頁面
response = ssion.get("http://www.renren.com/410043129/profile")

# 6. 列印響應內容
print(response.text)
# 將cookie物件轉為字典
cookieDict = requests.utils.dict_from_cookiejar(ssion.cookies)
# 儲存cookie
with open("session.txt", 'w', encoding='utf-8') as f:
    f.write(str(cookieDict))
    f.flush()

九、SSL證書驗證

https請求驗證ssl證書(有一些網站的ssl證書是自己寫的,比如12306和360)

  • 引數verify負責表示是否需要驗證ssL證書,預設是True
  • 如果不需要驗證ssl證書,則設定成False表示關閉

            rsp = requests.get("https://www.baidu.com", verify=False)
            # 如果用verify=True訪問12306,會報錯,因為他證書有問題 

 處理HTTPS請求 SSL證書驗證 ,Requests也可以為HTTPS請求驗證SSL證書:

要想檢查某個主機的SSL證書,你可以使用 verify 引數(也可以不寫)

import requests
response = requests.get("https://www.baidu.com/", verify=True)

# 也可以省略不寫
# response = requests.get("https://www.baidu.com/")
print(response.text)

如果SSL證書驗證不通過,或者不信任伺服器的安全證書,則會報出SSLError,據說 12306 證書是自己做的: 
來測試一下:

import requests
response = requests.get("https://www.12306.cn/mormhweb/")
print(response.text)

報錯:

SSLError: ("bad handshake: Error([('SSL routines', 
'ssl3_get_server_certificate', 'certificate verify failed')],)",)

如果我們想跳過 12306 的證書驗證,把 verify 設定為 False 就可以正常請求了。

import requests

url = "https://www.12306.cn/mormhweb/"
response = requests.get(url,verify=False)
print(response.text)