python网络爬虫系列(四)——requests模块
requests模塊
知識點:
- 掌握 headers參數(shù)的使用
- 掌握 發(fā)送帶參數(shù)的請求
- 掌握 headers中攜帶cookie
- 掌握 cookies參數(shù)的使用
- 掌握 cookieJar的轉(zhuǎn)換方法
- 掌握 超時參數(shù)timeout的使用
- 掌握 代理ip參數(shù)proxies的使用
- 掌握 使用verify參數(shù)忽略CA證書
- 掌握 requests模塊發(fā)送post請求
- 掌握 利用requests.session進行狀態(tài)保持
前面我們了解了爬蟲的基礎知識,接下來我們來學習如何在代碼中實現(xiàn)我們的爬蟲
1. requests模塊介紹
requests文檔http://docs.python-requests.org/zh_CN/latest/index.html
1.1 requests模塊的作用:
- 發(fā)送http請求,獲取響應數(shù)據(jù)
1.2 requests模塊是一個第三方模塊,需要在你的python(虛擬)環(huán)境中額外安裝
- pip/pip3 install requests
1.3 requests模塊發(fā)送get請求
需求:通過requests向百度首頁發(fā)送請求,獲取該頁面的源碼
運行下面的代碼,觀察打印輸出的結(jié)果
知識點:掌握 requests模塊發(fā)送get請求
2. response響應對象
觀察上邊代碼運行結(jié)果發(fā)現(xiàn),有好多亂碼;這是因為編解碼使用的字符集不同早造成的;我們嘗試使用下邊的辦法來解決中文亂碼問題
# 1.2.2-response.content import requests # 目標url url = 'https://www.baidu.com' # 向目標url發(fā)送get請求 response = requests.get(url)# 打印響應內(nèi)容 # print(response.text) print(response.content.decode()) # 注意這里!2.1 response.text 和response.content的區(qū)別:
- response.text
- 類型:str
- 解碼類型: requests模塊自動根據(jù)HTTP 頭部對響應的編碼作出有根據(jù)的推測,推測的文本編碼
- response.content
- 類型:bytes
- 解碼類型: 沒有指定
知識點:掌握 response.text和response.content的區(qū)別
2.2 通過對response.content進行decode,來解決中文亂碼
- response.content.decode() 默認utf-8
- response.content.decode("GBK")
- 常見的編碼字符集
- utf-8
- gbk
- gb2312
- ascii (讀音:阿斯克碼)
- iso-8859-1
知識點:掌握 利用decode函數(shù)對requests.content解決中文亂碼
2.3 response響應對象的其它常用屬性或方法
response = requests.get(url)中response是發(fā)送請求獲取的響應對象;response響應對象中除了text、content獲取響應內(nèi)容以外還有其它常用的屬性或方法:
- response.url響應的url;有時候響應的url和請求的url并不一致
- response.status_code 響應狀態(tài)碼
- response.request.headers 響應對應的請求頭
- response.headers 響應頭
- response.request._cookies 響應對應請求的cookie;返回cookieJar類型
- response.cookies 響應的cookie(經(jīng)過了set-cookie動作;返回cookieJar類型
- response.json()自動將json字符串類型的響應內(nèi)容轉(zhuǎn)換為python對象(dict or list)
知識點:掌握 response響應對象的其它常用屬性
3. requests模塊發(fā)送請求
3.1 發(fā)送帶header的請求
我們先寫一個獲取百度首頁的代碼
import requestsurl = 'https://www.baidu.com'response = requests.get(url)print(response.content.decode())# 打印響應對應請求的請求頭信息 print(response.request.headers)3.1.1 思考
對比瀏覽器上百度首頁的網(wǎng)頁源碼和代碼中的百度首頁的源碼,有什么不同?
- 查看網(wǎng)頁源碼的方法:
- 右鍵-查看網(wǎng)頁源代碼 或
- 右鍵-檢查
對比對應url的響應內(nèi)容和代碼中的百度首頁的源碼,有什么不同?
- 查看對應url的響應內(nèi)容的方法:
- 右鍵-檢查
- 點擊 Net work
- 勾選 Preserve log
- 刷新頁面
- 查看Name一欄下和瀏覽器地址欄相同的url的Response
代碼中的百度首頁的源碼非常少,為什么?
-
需要我們帶上請求頭信息
回顧爬蟲的概念,模擬瀏覽器,欺騙服務器,獲取和瀏覽器一致的內(nèi)容
-
請求頭中有很多字段,其中User-Agent字段必不可少,表示客戶端的操作系統(tǒng)以及瀏覽器的信息
3.1.2 攜帶請求頭發(fā)送請求的方法
requests.get(url, headers=headers)
- headers參數(shù)接收字典形式的請求頭
- 請求頭字段名作為key,字段對應的值作為value
3.1.3 完成代碼實現(xiàn)
從瀏覽器中復制User-Agent,構(gòu)造headers字典;完成下面的代碼后,運行代碼查看結(jié)果
import requestsurl = 'https://www.baidu.com'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"}# 在請求頭中帶上User-Agent,模擬瀏覽器發(fā)送請求 response = requests.get(url, headers=headers) print(response.content)# 打印請求頭信息 print(response.request.headers)知識點:掌握 headers參數(shù)的使用
3.2 發(fā)送帶參數(shù)的請求
我們在使用百度搜索的時候經(jīng)常發(fā)現(xiàn)url地址中會有一個 ?,那么該問號后邊的就是請求參數(shù),又叫做查詢字符串
3.2.1 在url攜帶參數(shù)
直接對含有參數(shù)的url發(fā)起請求
import requestsheaders = {"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"}url = 'https://www.baidu.com/s?wd=python'response = requests.get(url, headers=headers)3.2.2 通過params攜帶參數(shù)字典
? 1.構(gòu)建請求參數(shù)字典
? 2.向接口發(fā)送請求的時候帶上參數(shù)字典,參數(shù)字典設置給params
import requestsheaders = {"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"}# 這是目標url # url = 'https://www.baidu.com/s?wd=python'# 最后有沒有問號結(jié)果都一樣 url = 'https://www.baidu.com/s?'# 請求參數(shù)是一個字典 即wd=python kw = {'wd': 'python'}# 帶上請求參數(shù)發(fā)起請求,獲取響應 response = requests.get(url, headers=headers, params=kw)print(response.content)知識點:掌握發(fā)送帶參數(shù)的請求的方法
3.3 在headers參數(shù)中攜帶cookie
網(wǎng)站經(jīng)常利用請求頭中的Cookie字段來做用戶訪問狀態(tài)的保持,那么我們可以在headers參數(shù)中添加Cookie,模擬普通用戶的請求。我們以github登陸為例:
3.3.1 github登陸抓包分析
3.3.2 完成代碼
- 從瀏覽器中復制User-Agent和Cookie
- 瀏覽器中的請求頭字段和值與headers參數(shù)中必須一致
- headers請求參數(shù)字典中的Cookie鍵對應的值是字符串
3.3.3 運行代碼驗證結(jié)果
在打印的輸出結(jié)果中搜索title,html中的標題文本內(nèi)容如果是你的github賬號,則成功利用headers參數(shù)攜帶cookie,獲取登陸后才能訪問的頁面
知識點:掌握 headers中攜帶cookie
3.4 cookies參數(shù)的使用
上一小節(jié)我們在headers參數(shù)中攜帶cookie,也可以使用專門的cookies參數(shù)
cookies參數(shù)的形式:字典
cookies = {"cookie的name":"cookie的value"}
- 該字典對應請求頭中Cookie字符串,以分號、空格分割每一對字典鍵值對
- 等號左邊的是一個cookie的name,對應cookies字典的key
- 等號右邊對應cookies字典的value
cookies參數(shù)的使用方法
response = requests.get(url, cookies)
將cookie字符串轉(zhuǎn)換為cookies參數(shù)所需的字典:
cookies_dict = {cookie.split('=')[0]:cookie.split('=')[-1] for cookie in cookies_str.split('; ')}
注意:cookie一般是有過期時間的,一旦過期需要重新獲取
知識點:掌握 cookies參數(shù)的使用
3.5 cookieJar對象轉(zhuǎn)換為cookies字典的方法
使用requests獲取的resposne對象,具有cookies屬性。該屬性值是一個cookieJar類型,包含了對方服務器設置在本地的cookie。我們?nèi)绾螌⑵滢D(zhuǎn)換為cookies字典呢?
轉(zhuǎn)換方法
cookies_dict = requests.utils.dict_from_cookiejar(response.cookies)
其中response.cookies返回的就是cookieJar類型的對象
requests.utils.dict_from_cookiejar函數(shù)返回cookies字典
知識點:掌握 cookieJar的轉(zhuǎn)換方法
3.6 超時參數(shù)timeout的使用
在平時網(wǎng)上沖浪的過程中,我們經(jīng)常會遇到網(wǎng)絡波動,這個時候,一個請求等了很久可能任然沒有結(jié)果。
在爬蟲中,一個請求很久沒有結(jié)果,就會讓整個項目的效率變得非常低,這個時候我們就需要對請求進行強制要求,讓他必須在特定的時間內(nèi)返回結(jié)果,否則就報錯。
超時參數(shù)timeout的使用方法
response = requests.get(url, timeout=3)
timeout=3表示:發(fā)送請求后,3秒鐘內(nèi)返回響應,否則就拋出異常
知識點:掌握 超時參數(shù)timeout的使用
3.7 了解代理以及proxy代理參數(shù)的使用
proxy代理參數(shù)通過指定代理ip,讓代理ip對應的正向代理服務器轉(zhuǎn)發(fā)我們發(fā)送的請求,那么我們首先來了解一下代理ip以及代理服務器
3.7.1 理解使用代理的過程
3.7.2 正向代理和反向代理的區(qū)別
前邊提到proxy參數(shù)指定的代理ip指向的是正向的代理服務器,那么相應的就有反向服務器;現(xiàn)在來了解一下正向代理服務器和反向代理服務器的區(qū)別
- 瀏覽器知道最終處理請求的服務器的真實ip地址,例如VPN
- 瀏覽器不知道服務器的真實地址,例如nginx
3.7.3 代理ip(代理服務器)的分類
根據(jù)代理ip的匿名程度,代理IP可以分為下面三類:
-
透明代理(Transparent Proxy):透明代理雖然可以直接“隱藏”你的IP地址,但是還是可以查到你是誰。目標服務器接收到的請求頭如下:
REMOTE_ADDR = Proxy IP HTTP_VIA = Proxy IP HTTP_X_FORWARDED_FOR = Your IP -
匿名代理(Anonymous Proxy):使用匿名代理,別人只能知道你用了代理,無法知道你是誰。目標服務器接收到的請求頭如下:
REMOTE_ADDR = proxy IP HTTP_VIA = proxy IP HTTP_X_FORWARDED_FOR = proxy IP -
高匿代理(Elite proxy或High Anonymity Proxy):高匿代理讓別人根本無法發(fā)現(xiàn)你是在用代理,所以是最好的選擇。毫無疑問使用高匿代理效果最好。目標服務器接收到的請求頭如下:
REMOTE_ADDR = Proxy IP HTTP_VIA = not determined HTTP_X_FORWARDED_FOR = not determined
根據(jù)網(wǎng)站所使用的協(xié)議不同,需要使用相應協(xié)議的代理服務。從代理服務請求使用的協(xié)議可以分為:
- http代理:目標url為http協(xié)議
- https代理:目標url為https協(xié)議
- socks隧道代理(例如socks5代理)等:
- socks 代理只是簡單地傳遞數(shù)據(jù)包,不關(guān)心是何種應用協(xié)議(FTP、HTTP和HTTPS等)。
- socks 代理比http、https代理耗時少。
- socks 代理可以轉(zhuǎn)發(fā)http和https的請求
3.7.4 proxies代理參數(shù)的使用
為了讓服務器以為不是同一個客戶端在請求;為了防止頻繁向一個域名發(fā)送請求被封ip,所以我們需要使用代理ip;那么我們接下來要學習requests模塊是如何使用代理ip的
-
用法:
response = requests.get(url, proxies=proxies) -
proxies的形式:字典
-
例如:
proxies = { "http": "http://12.34.56.79:9527", "https": "https://12.34.56.79:9527", } -
注意:如果proxies字典中包含有多個鍵值對,發(fā)送請求時將按照url地址的協(xié)議來選擇使用相應的代理ip
知識點:掌握 代理ip參數(shù)proxies的使用
3.8 使用verify參數(shù)忽略CA證書
在使用瀏覽器上網(wǎng)的時候,有時能夠看到下面的提示(2018年10月之前的12306網(wǎng)站):
- 原因:該網(wǎng)站的CA證書沒有經(jīng)過【受信任的根證書頒發(fā)機構(gòu)】的認證
- 關(guān)于CA證書以及受信任的根證書頒發(fā)機構(gòu)點擊了解更多,課上我們不做展開
3.8.1 運行代碼查看代碼中向不安全的鏈接發(fā)起請求的效果
運行下面的代碼將會拋出包含ssl.CertificateError ...字樣的異常
import requests url = "https://sam.huat.edu.cn:8443/selfservice/" response = requests.get(url)3.8.2 解決方案
為了在代碼中能夠正常的請求,我們使用verify=False參數(shù),此時requests模塊發(fā)送請求將不做CA證書的驗證:verify參數(shù)能夠忽略CA證書的認證
import requests url = "https://sam.huat.edu.cn:8443/selfservice/" response = requests.get(url,verify=False)知識點:掌握 使用verify參數(shù)忽略CA證書
4. requests模塊發(fā)送post請求
思考:哪些地方我們會用到POST請求?
所以同樣的,我們的爬蟲也需要在這兩個地方回去模擬瀏覽器發(fā)送post請求
4.1 requests發(fā)送post請求的方法
-
response = requests.post(url, data)
-
data參數(shù)接收一個字典
-
requests模塊發(fā)送post請求函數(shù)的其它參數(shù)和發(fā)送get請求的參數(shù)完全一致
4.2 POST請求練習
下面面我們通過金山翻譯的例子看看post請求如何使用:
地址:http://fy.iciba.com/
思路分析
抓包確定請求的url地址
確定請求的參數(shù)
確定返回數(shù)據(jù)的位置
模擬瀏覽器獲取數(shù)據(jù)
4.2.3 抓包分析的結(jié)論
url地址:http://fy.iciba.com/
請求方法:POST
請求所需參數(shù):
data = {'f': 'auto', # 表示被翻譯的語言是自動識別't': 'auto', # 表示翻譯后的語言是自動識別'w': '人生苦短' # 要翻譯的中文字符串 }pc端User-Agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
4.2.4 代碼實現(xiàn)
了解requests模塊發(fā)送post請求的方法,以及分析過移動端的百度翻譯之后,我們來完成代碼
import requests import jsonclass King(object):def __init__(self, word):self.url = "http://fy.iciba.com/ajax.php?a=fy"self.word = wordself.headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"}self.post_data = {"f": "auto","t": "auto","w": self.word}def get_data(self):response = requests.post(self.url, headers=self.headers, data=self.post_data)# 默認返回bytes類型,除非確定外部調(diào)用使用str才進行解碼操作return response.contentdef parse_data(self, data):# 將json數(shù)據(jù)轉(zhuǎn)換成python字典dict_data = json.loads(data)# 從字典中抽取翻譯結(jié)果try:print(dict_data['content']['out'])except:print(dict_data['content']['word_mean'][0])def run(self):# url# headers# post——data# 發(fā)送請求data = self.get_data()# 解析self.parse_data(data)if __name__ == '__main__':# king = King("人生苦短,及時行樂")king = King("China")king.run()# python標準庫有很多有用的方法,每天看一個標準庫的使用知識點:掌握 requests模塊發(fā)送post請求
5. 利用requests.session進行狀態(tài)保持
requests模塊中的Session類能夠自動處理發(fā)送請求獲取響應過程中產(chǎn)生的cookie,進而達到狀態(tài)保持的目的。接下來我們就來學習它
5.1 requests.session的作用以及應用場景
- requests.session的作用
- 自動處理cookie,即 下一次請求會帶上前一次的cookie
- requests.session的應用場景
- 自動處理連續(xù)的多次請求過程中產(chǎn)生的cookie
5.2 requests.session使用方法
session實例在請求了一個網(wǎng)站后,對方服務器設置在本地的cookie會保存在session中,下一次再使用session請求對方服務器的時候,會帶上前一次的cookie
session = requests.session() # 實例化session對象 response = session.get(url, headers, ...) response = session.post(url, data, ...)- session對象發(fā)送get或post請求的參數(shù),與requests模塊發(fā)送請求的參數(shù)完全一致
5.3 課堂測試
使用requests.session來完成github登陸,并獲取需要登陸后才能訪問的頁面
5.3.1 提示
- 部分請求參數(shù)在別的url對應的響應內(nèi)容中,可以使用re模塊獲取
5.3.2 參考代碼
- myCode
知識點:掌握 利用requests.session進行狀態(tài)保持
實例化session對象
session = requests.session()
訪問登陸頁獲取登陸請求所需參數(shù)
response = session.get(‘https://github.com/login’, headers=headers)
authenticity_token = re.search(‘name=“authenticity_token” value="(.*?)" />’, response.text).group(1) # 使用正則獲取登陸請求所需參數(shù)
構(gòu)造登陸請求參數(shù)字典
data = {
‘commit’: ‘Sign in’, # 固定值
‘utf8’: ‘?’, # 固定值
‘a(chǎn)uthenticity_token’: authenticity_token, # 該參數(shù)在登陸頁的響應內(nèi)容中
‘login’: input(‘輸入github賬號:’),
‘password’: input(‘輸入github賬號:’)
}
發(fā)送登陸請求(無需關(guān)注本次請求的響應)
session.post(‘https://github.com/session’, headers=headers, data=data)
打印需要登陸后才能訪問的頁面
response = session.get(‘https://github.com/1596930226’, headers=headers)
print(response.text)
總結(jié)
以上是生活随笔為你收集整理的python网络爬虫系列(四)——requests模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二十、PHP框架Laravel学习笔记—
- 下一篇: 五、手动取消ajax请求 解决重复发送