使用 requests 獲取的 resposne 對象,具有 cookies 屬性。該屬性值是一個(gè) cookieJar 類(lèi)型,包含了對方服務(wù)器設置在本地的 cookie 。我們如何將其轉換為 cookies 字典呢?
? 1. 轉換方法
cookies_dict = requests.utils.dict_from_cookiejar(response.cookies)
? 2. 其中 response.cookies 返回的就是 cookieJar 類(lèi)型的對象
? 3. requests.utils.dict_from_cookiejar 函數返回 cookies 字典
import requests
import re
url = 'https://www.zhihu.com/creator'
cookies_str = '復制的cookies'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
cookie_dict = {cookie.split('=', 1)[0]:cookie.split('=', 1)[-1] for cookie in
cookies_str.split('; ')}
# 請求頭參數字典中攜帶cookie字符串
resp = requests.get(url, headers=headers, cookies=cookies_dict)
data = re.findall('CreatorHomeAnalyticsDataItem-title.*?>(.*?)</div>',resp.text)
print(resp.status_code)
print(data)
# 可以把一個(gè)字典轉化為一個(gè)requests.cookies.RequestsCookieJar對象
cookiejar = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None,
overwrite=True)
type(cookiejar) # requests.cookies.RequestsCookieJar
type(resp.cookies) # requests.cookies.RequestsCookieJar
#構造RequestsCookieJar對象進(jìn)行cookies設置其中jar的類(lèi)型也是 requests.cookies.
RequestsCookieJar
#cookiejar轉字典
requests.utils.dict_from_cookiejar(cookiejar)
在平時(shí)網(wǎng)上沖浪的過(guò)程中,我們經(jīng)常會(huì )遇到網(wǎng)絡(luò )波動(dòng),這個(gè)時(shí)候,一個(gè)請求等了很久可能任 然沒(méi)有結果。微信搜索公眾號:架構師指南,回復:架構師 領(lǐng)取資料 。
在爬蟲(chóng)中,一個(gè)請求很久沒(méi)有結果,就會(huì )讓整個(gè)項目的效率變得非常低,這個(gè)時(shí)候我們就需 要對請求進(jìn)行強制要求,讓他必須在特定的時(shí)間內返回結果,否則就報錯。
? 1. 超時(shí)參數 timeout 的使用方法
response = requests.get(url, timeout=3)
? 2. timeout=3 表示:發(fā)送請求后, 3 秒鐘內返回響應,否則就拋出異常
url = 'http://www.tipdm.com/tipdm/index.html'
#設置超時(shí)時(shí)間為2
print('超時(shí)時(shí)間為2:',requests.get(url,timeout=2))
requests.get(url,timeout = 0.1) #備注時(shí)間為0.001
超時(shí)時(shí)間為 2: <Response [200]>

思考:哪些地方我們會(huì )用到POST請求?
1.登錄注冊(在 web 工程師看來(lái) POST 比 GET 更安全, url 地址中不會(huì )暴露用戶(hù)的賬號密碼等信息)
2.需要傳輸大文本內容的時(shí)候( POST 請求對數據長(cháng)度沒(méi)有要求)
所以同樣的,我們的爬蟲(chóng)也需要在這兩個(gè)地方回去模擬瀏覽器發(fā)送 post 請求其實(shí)發(fā)送 POST 請求與 GET 方式很相似,只是參數的傳遞我們需要定義在 data 中即可:
POST參數說(shuō)明:
post(url, data=None, json=None, **kwargs):
? URL: 待請求的網(wǎng)址
? data :( 可選 ) 字典,元組列表,字節或類(lèi)似文件的對象,以在 Request 的正文中發(fā)送
? json: ( 可選 )JSON 數據,發(fā)送到 Request 類(lèi)的主體中。
? **kwargs: 可變長(cháng)關(guān)鍵字參數
import requests
payload = {’key1’: ’value1’, ’key2’: ’value2’}
req = requests.post('http://httpbin.org/post', data=payload)
print(req.text)
很多時(shí)候你想要發(fā)送的數據并非編碼為表單形式的 , 發(fā)現特別在爬取很多java網(wǎng)址中出現這個(gè)問(wèn)題。如果你傳遞一個(gè) string而不是一個(gè)dict ,那么數據會(huì )被直接發(fā)布出去。我們可以使用json.dumps()是將 dict 轉化成str格式 ; 此處除了可以自行對dict進(jìn)行編碼,你還可以使用json參數直接傳遞,然后它就會(huì )被自動(dòng)編碼。
import json
import requests
url = ’http://httpbin.org/post’
payload = {’some’: ’data’}
req1 = requests.post(url, data=json.dumps(payload))
req2 = requests.post(url, json=payload)
print(req1.text)
print(req2.text)
可以發(fā)現,我們成功獲得了返回結果,其中 form 部分就是提交的數據,這就證明 POST 請求 成功發(fā)送了。
筆記
requests 模塊發(fā)送請求有 data 、 json 、 params 三種攜帶參數的方法。
params 在 get 請求中使用, data 、 json 在 post 請求中使用。
data 可以接收的參數為:字典,字符串,字節,文件對象。
? 使用 json 參數,不管報文是 str 類(lèi)型,還是 dict 類(lèi)型,如果不指定 headers 中 content-type 的
類(lèi)型,默認是:application/json 。
? 使用 data 參數,報文是 dict 類(lèi)型,如果不指定 headers 中 content-type 的類(lèi)型,默認 application/x
www-form-urlencoded ,相當于普通 form 表單提交的形式,會(huì )將表單內的數據轉換成鍵值對,此時(shí)數據可以從 request.POST 里面獲取,而 request.body 的內容則為 a=1&b=2 的這種鍵值對形式。
? 使用 data 參數,報文是 str 類(lèi)型,如果不指定 headers 中 content-type 的類(lèi)型,默認 application/json。
用 data 參數提交數據時(shí), request.body 的內容則為 a=1&b=2 的這種形式,
用 json 參數提交數據時(shí), request.body 的內容則為 ’'a': 1, 'b': 2’ 的這種形式
如果我們要使用爬蟲(chóng)上傳文件,可以使用 fifile 參數:
url = 'http://httpbin.org/post'
files = {'file': open('test.xlsx', 'rb')}
req = requests.post(url, files=files)
req.text
如果有熟悉 WEB 開(kāi)發(fā)的伙伴應該知道,如果你發(fā)送一個(gè)非常大的文件作為 multipart/form data 請求,你可能希望將請求做成數據流。默認下 requests 不支持 , 你可以使用 requests-toolbelt 三方庫。
主要是找到待解析的網(wǎng)頁(yè)
import requests
# 準備翻譯的數據
kw =
input('請輸入要翻譯的詞語(yǔ):')
ps = {'kw': kw}
# 準備偽造請求
headers = {
# User-Agent:首字母大寫(xiě),表示請求的身份信息;一般直接使用瀏覽器的身份信息,偽造
爬蟲(chóng)請求
# 讓瀏覽器認為這個(gè)請求是由瀏覽器發(fā)起的[隱藏爬蟲(chóng)的信息]
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Edg/85.0.564.41'
}
# 發(fā)送POST請求,附帶要翻譯的表單數據--以字典的方式進(jìn)行傳遞
response = requests.post('https://fanyi.baidu.com/sug', data=ps)
# 打印返回的數據
# print(response.content)
print(response.content.decode('unicode_escape'))

在這一部分主要介紹關(guān)于 Session 會(huì )話(huà)維持,以及代理 IP 的使用。
在requests中,如果直接利用get()或post()等方法的確可以做到模擬網(wǎng)頁(yè)的請求,但是這實(shí)際上是相當于不同的會(huì )話(huà),也就是說(shuō)相當于你用了兩個(gè)瀏覽器打開(kāi)了不同的頁(yè)面。
設想這樣一個(gè)場(chǎng)景,第一個(gè)請求利用post() 方法登錄了某個(gè)網(wǎng)站,第二次想獲取成功登錄后的自己的個(gè)人信息, 你又用了一次get()方法去請求個(gè)人信息頁(yè)面。實(shí)際上,這相當于打開(kāi)了兩個(gè)瀏覽器,這是兩個(gè)完全不相關(guān)的會(huì )話(huà),能成功獲取個(gè)人信息嗎?那當然不能。
有小伙伴可能說(shuō)了,我在兩次請求時(shí)設置一樣的cookies不就行了?可以,但這樣做起來(lái)顯 得很煩瑣,我們有更簡(jiǎn)單的解決方法。
其實(shí)解決這個(gè)問(wèn)題的主要方法就是維持同一個(gè)會(huì )話(huà),也就是相當于打開(kāi)一個(gè)新的瀏覽器選項 卡而不是新開(kāi)一個(gè)瀏覽器。但是我又不想每次設置cookies,那該怎么辦呢?這時(shí)候就有了新的 利器一Session對象。
利用它,我們可以方便地維護一個(gè)會(huì )話(huà),而且不用擔心 cookies 的問(wèn)題,它 會(huì )幫我們自動(dòng)處理好。
requests模塊中的Session類(lèi)能夠自動(dòng)處理發(fā)送請求獲取響應過(guò)程中產(chǎn)生的cookie,進(jìn)而達到狀態(tài)保持的目的。接下來(lái)我們就來(lái)學(xué)習它。
? requests.session 的作用
自動(dòng)處理 cookie , 即下一次請求會(huì )帶上前一次的 cookie
? requests.session 的應用場(chǎng)景
自動(dòng)處理連續的多次請求過(guò)程中產(chǎn)生的cookie
session 實(shí)例在請求了一個(gè)網(wǎng)站后,對方服務(wù)器設置在本地的 cookie 會(huì )保存在 session 中,下 一次再使用 session 請求對方服務(wù)器的時(shí)候,會(huì )帶上前一次的 cookie。
session = requests . session () # 實(shí) 例 化 session 對 象
response = session . get ( url , headers , ...)
response = session . post ( url , data , ...)
session 對象發(fā)送 get 或 post 請求的參數,與 requests 模塊發(fā)送請求的參數完全一致。
? 對 github 登陸以及訪(fǎng)問(wèn)登陸后才能訪(fǎng)問(wèn)的頁(yè)面的整個(gè)完成過(guò)程進(jìn)行抓包
? 確定登陸請求的 url 地址、請求方法和所需的請求參數
-部分請求參數在別的 url 對應的響應內容中,可以使用 re 模塊獲取
? 確定登陸后才能訪(fǎng)問(wèn)的頁(yè)面的的 url 地址和請求方法
? 利用 requests.session 完成代碼
import requests
import re
# 構造請求頭字典
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',}
# 實(shí)例化session對象
session = requests.session()
# 訪(fǎng)問(wèn)登陸頁(yè)獲取登陸請求所需參數
response = session.get(https://github.com/login, headers=headers)
authenticity_token = re.search('name='authenticity_token' value='(.*?)' />',
response.text).group(1) # 使用正則獲取登陸請求所需參數
# 構造登陸請求參數字典
data = {
'commit': 'Sign in', # 固定值
'utf8': ' ', # 固定值
'authenticity_token': authenticity_token, # 該參數在登陸頁(yè)的響應內容中
'login':
input('輸入github賬號:'),
'password':
input('輸入github賬號:')}
# 發(fā)送登陸請求(無(wú)需關(guān)注本次請求的響應)
session.post(https://github.com/session, headers=headers, data=data)
# 打印需要登陸后才能訪(fǎng)問(wèn)的頁(yè)面
response = session.get(https://github.com/settings/profile, headers=headers)
print(response.text)
可以使用文本對比工具進(jìn)行校對 !
人生苦短,我用python
【神秘禮包獲取方式】
聯(lián)系客服