python爬蟲2:requests庫-原理
前言
? python實現(xiàn)網(wǎng)絡爬蟲非常簡單,只需要掌握一定的基礎知識和一定的庫使用技巧即可。本系列目標旨在梳理相關(guān)知識點,方便以后復習。
目錄結(jié)構(gòu)
1. 概述
? python其實自帶一個請求庫,即urllib,不過這個庫并不是很好使,因此大部人都還是采用的第三方庫requests。
? Request支持HTTP連接保持和連接池,支持使用cookie保持會話,支持文件上傳,支持自動響應內(nèi)容的編碼,支持國際化的URL和POST數(shù)據(jù)自動編碼。
? 在python內(nèi)置模塊的基礎上進行了高度的封裝,從而使得python進行網(wǎng)絡請求時,變得人性化,使用Requests可以輕而易舉的完成瀏覽器可有的任何操作。
? 另外,requests的安裝十分簡單,僅需要pip一下即可:
pip install requests
? 如果網(wǎng)不好,還可以指定鏡像源,下載更快:
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
? 可以使用以下代碼檢驗是否安裝成功:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.content.decode('utf-8'))
? 返回結(jié)果如下:
2. response對象
? 當我們使用get、post或者其他方式去請求的時候,我們就會得到一個response對象(比如上面測試代碼中g(shù)et函數(shù)返回的對象),你可以稱呼它為響應對象,下面我們來學習這個對象的常用屬性和方法。
2.1 encoding屬性
? 作用: 返回網(wǎng)頁的編碼格式。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.encoding)
? 打印結(jié)果為:
ISO-8859-1
? 這個結(jié)果也是編碼的一種,不過是我們國內(nèi)的標準,其他常見的有utf-8之類的。
2.2 url屬性
? 作用: 返回響應服務器的url。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.url)
? 打印結(jié)果為:
https://www.baidu.com/
? 不要小瞧這個屬性。有時候我們訪問的是:http://www.test.com
,但是由于這個網(wǎng)站有重定向,因此我們實際訪問的是: http://www.good.com
,這樣我們通過這個屬性確定我們真實訪問的網(wǎng)址。
2.3 status_code屬性
? 作用: 返回響應的狀態(tài)碼。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.status_code)
? 打印結(jié)果為:
200
什么是狀態(tài)碼?
? 簡單來說就是你訪問的這個網(wǎng)站狀態(tài)怎么樣,是正常訪問,還是說服務器錯誤,還是網(wǎng)絡有問題等等。
? 這里介紹一下常見的相應狀態(tài)碼:
2xx | 正常
3xx | 重定向
4xx | 錯誤
5xx | 服務器錯誤
2.4 cookies屬性
? 作用: 返回cookie對象。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.cookies)
? 打印結(jié)果:
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
什么是cookie?
? 這里簡單說明一下什么是cookie,可以簡單理解為一個存在我們電腦本地的臨時身份文件,比如你訪問一個網(wǎng)站,你首次登錄了它,然后你把這個網(wǎng)站關(guān)掉,再次打開,發(fā)現(xiàn)不需要重新登錄,這就是cookie發(fā)揮了作用,當你登陸后,在本地創(chuàng)建了一個臨時文件用于后期登錄。
2.5 request.headers屬性
? 作用: 返回請求頭。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.request.headers)
? 打印的值為:
{'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
什么是請求頭?
? 簡單來說,你訪問一個網(wǎng)站,比如百度搜索,你肯定會搜索某個東西,那么自然你請求這個網(wǎng)站,發(fā)送給這個網(wǎng)站的信息中帶有這個東西,我們一般稱之為請求頭,其包含了你所請求的所有信息。
? 從上面的返回值可以看出一點:百度網(wǎng)站知道你是python腳本,從'User-Agent': 'python-requests/2.31.0'
就可以看出。因此,我們寫爬蟲的時候必須要做一定的偽裝,不然直接就被識別出來是爬蟲了。
2.6 headers屬性
? 作用: 返回響應頭。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.headers)
? 打印結(jié)果:
{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Fri, 04 Aug 2023 05:36:28 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:23:55 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
什么是響應頭?
? 響應頭就是服務器/網(wǎng)站自身返回給我們的部分信息、
2.7 text屬性
? 作用: 返回網(wǎng)頁的源碼,但是是按照chardet模塊推測出的編碼進行解碼的結(jié)果(不準確)。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.text)
? 返回結(jié)果:
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>????o|??€???????? ?°±??¥é?“</title></head> <body link=#0000cc> <div id=wrapper>
....
# 部分結(jié)果
? 說明:text返回的是網(wǎng)頁源碼,但是解碼時是推測的,有時候并不準確。因此,我們更加常用content屬性,加上自己解碼,更加準確。
2.8 content屬性
? 作用: 返回網(wǎng)頁源代碼的bytes形式的結(jié)果。
? 代碼:
import requests
# 網(wǎng)址
url = 'https://www.baidu.com'
# 請求
response = requests.get(url)
# 打印返回結(jié)果
print(response.content.decode('utf-8'))
? 打印的部分結(jié)果:
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head>
....
# 部分結(jié)果
如何判斷網(wǎng)頁編碼形式?
? 這個簡單,隨便打開一個網(wǎng)頁,比如百度,點擊鼠標右鍵,查看源碼,找到下圖中的內(nèi)容(html網(wǎng)頁源碼整體框架是固定的,因此你在任何網(wǎng)頁上都可以找到類似的內(nèi)容):
3. GET請求
3.1 方法概述
? get請求是平時我們最常用的請求方式之一。在requests模塊中,提供給我們了非常方便的get請求方式:
import requests
url = 'http://www.baidu.com'
response = requests.get(url)
print(response.status_code)
3.2 常用參數(shù)
參數(shù) | 作用 |
---|---|
url | 請求的地址 |
headers | 請求頭參數(shù)(字典) |
params | 請求的參數(shù)(字典) |
cookies | 請求的cookies參數(shù)(字典) |
timeout | 超時時間設置 |
3.2 參數(shù)的用法舉例
? 這里舉一個簡單的例子,來說明一下這些參數(shù)怎么用。
? 之前不是說了嘛,直接用腳本去訪問百度網(wǎng)站,會被識別出是python腳本,因此我們可以利用請求頭參數(shù)進行簡單的偽裝:
import requests
# 地址
url = 'https://www.baidu.com'
# 偽造請求頭
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
}
# 訪問
response = requests.get(url,headers=headers)
# 打印
print(response.request.headers)
? 注意:傳入的參數(shù)必須為字典形式,內(nèi)容必須符合請求頭的內(nèi)容。
? 打印的結(jié)果如下:
{'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
? 可以看出,確實偽造成功了。
如何正確書寫請求頭格式?
? 這一點很重要也很簡單,你隨便打開一個網(wǎng)頁,鼠標右鍵,選擇”檢查“(Google瀏覽器為例),然后按下圖操作,即可看見請求頭內(nèi)容:
? 這里我介紹一下最常見的請求頭參數(shù)內(nèi)容:
User-Agent : 客戶端瀏覽器的版本信息
Host : 服務器的主機
Referer:表示從哪個頁面跳轉(zhuǎn)到當前的頁面
Cookie:用于記錄客戶端的身份信息,例如通過cookie登錄網(wǎng)站
x-forward-for:表示客戶端的IP地址,一般被稱為”XXF“頭,服務器通過這個字段可以知道客戶端的真實IP或代理IP
? (params參數(shù)后面單獨出一個案例講解)
4. POST請求
? post請求也是我們網(wǎng)站中最常用的請求方式之一,一般提交表單幾乎都是post請求。而,在requests模塊中,post請求與get請求的使用方法上差別在于參數(shù)(params變?yōu)榱?/strong>data,headers參數(shù)和其他參數(shù)是相同的):
data: 接收一個字典,里面爬蟲發(fā)出的數(shù)據(jù)
5. 代理設置
? 使用代理,可以減少我們自己真實IP暴漏的概率。
? 簡單來說,代理就是使用別人IP來訪問網(wǎng)站,這樣網(wǎng)站如果進行檢測,只能檢測到別人的IP地址,根本不知道其實是你在訪問他的網(wǎng)站。
? 一般代理IP按照匿名程度分為:
- 高匿:
- 別人不知道你的真實IP
- 透明:
- 別人知道你的真實IP
? 而,在requests庫中,get、post請求方法中都有一個參數(shù) proxies
,這個參數(shù)就是設置代理使用的。
? 使用方法如下:
import requests
proxies = {
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port',
'http/https':'http/https:ip:port'
}
requests.get(url,proxies=proxies)
? 當我們需要追求效率時,除了可以采用多任務的方式,還有一個方式就是使用代理。比如我們需要下載圖片,為了不被網(wǎng)站檢測出我們是爬蟲,我們不得不犧牲效率,比如說每爬取一張圖片就休息一秒鐘,這樣的效率顯然很低。但是一旦我們一秒鐘爬取個幾百張圖片,非常容易被網(wǎng)站檢測出這個用戶不是一個人,因為真正的人不可能一秒鐘下載幾百張圖片,于是網(wǎng)站便會短時間封禁我們的ip,導致我們無法繼續(xù)訪問,以至于爬蟲失效。
? 這時我們需要代理,這樣我們就可以在爬取的時候使用不同的ip地址了。
? 那么總結(jié)一下,為什么需要代理呢?
- 減少自己真實IP暴漏的概率
- 可以使用多個代理IP來實現(xiàn)快速訪問
因為,現(xiàn)在的網(wǎng)站幾乎都會屏蔽速度過快的訪問,比如一秒幾十次乃至幾百、上千萬次的訪問,這樣的訪問一看就不正常,因此站長幾乎都會屏蔽乃至禁止你的IP,因此我們可以使用多個代理IP,比如我們使用100個,那么我們每秒就會訪問100次都不會有任何的問題
6. 會話維持
? 我們有時候遇見一些網(wǎng)站會強制你登錄才能去獲取數(shù)據(jù)。此時你知道想要登錄網(wǎng)站需要去使用post方式請求,但是當你請求成功后再用get方式去訪問網(wǎng)站,你會發(fā)現(xiàn)你被拒絕了,這意味著你的get請求是一個新的請求,而不是在post請求成功后以post為基礎的請求。如果你無法理解上面的話,你可以這樣理解,一個get就是打開一個瀏覽器,兩個瀏覽器之間是無法通信的,所以你第二次請求相當于打開一個新的瀏覽器,自然無法獲取內(nèi)容。
? 因此,我們需要一些方法來搞定這個問題。
? 參考代碼如下:
#下面給出的是思路,不是具體的代碼,具體的代碼還是根據(jù)實際案例來講
import requests
#創(chuàng)建session對象
session = requests.session()
#使用session對象去發(fā)送post請求
session.post(.....) #這里post的用法和requests.post()用法一致
#請求成功后再用session對象去請求只有登錄才能訪問的頁面
response = session.get(....) #這里post的用法和requests.get()用法一致
#接下來再去操作即可
? (這個也會單獨出一篇講解案例)
7. ssl證書
? 有時候,我們的爬蟲需要忽略ssl證書,即我們手動訪問的時候會顯示這個網(wǎng)頁不安全/ssl證書過期等提示。
? 忽略的方法很簡單,參考如下:文章來源:http://www.zghlxwxcb.cn/news/detail-629725.html
import requests
response = requests.get('https://www.baidu.com',verify=False)
print(response.status_code)
8. 總結(jié)
? 本篇文章主要梳理了requests常用方法,接下來的文章會對本文中涉及的一些方法進行舉例說明。文章來源地址http://www.zghlxwxcb.cn/news/detail-629725.html
到了這里,關(guān)于python爬蟲2:requests庫-原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!