equests庫的七個主要方法:
r=requests.get(url) :
構(gòu)造一個向服務(wù)器請求資源的Request對象(Request),并且get方法返回一個包含服務(wù)器資源的Response對象;
requests.get函數(shù)的完整參數(shù)如下:
requests.get(url, params=None, **kwargs)
url: 擬獲取頁面的url鏈接
params: url中額外參數(shù),字典或字節(jié)流格式,可選
**kwargs: 12個控 訪問的參數(shù)
Requests庫的2個重要的對象 Request 和 Response對象(Response對象包含爬蟲返回的所有內(nèi)容)
>>> import requests #導(dǎo)入requests庫
>>> r=requests.get("http://www.baidu.com")
>>> print(r.status_code) #檢測請求的狀態(tài)碼,200表示請求成功
200
>>> type(r)
<class 'requests.models.Response'>
>>> r.headers
Response對象的屬性:
Response對象的處理流程如下圖示:
理解Response的編碼:
r.encoding:如果header中不存在charset,則認(rèn)為編碼為'ISO-8859-1'
r.apparent_encoding: 根據(jù)網(wǎng)頁內(nèi)容分析出的編碼方式
需求:獲取京東頁面數(shù)據(jù)
import requests
resp=requests.get('http:www.jd.com/')
print(resp)
requests模塊如何處理攜帶參數(shù)的get請求,返回攜帶參數(shù)的請求:
需求:指定一個詞條,獲取搜狗搜索結(jié)果所對應(yīng)的頁面數(shù)據(jù)
之前urllib模塊處理url上參數(shù)有中文的需要處理編碼,requests會自動處理url編碼
發(fā)起帶參數(shù)的get請求
params可以是傳字典或者列表
def get(url, params=None, **kwargs):
r"""Sends a GET request.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
import requests
# 指定url
url='https://www.sogou.com/web'
# 封裝get請求參數(shù)
prams={
'query':'周杰倫',
'ie':'utf-8'
}
response=requests.get(url=url,params=prams)
page_text=response.text
with open("周杰倫.html","w",encoding="utf-8") as f:
f.write(page_text)
f.close()
print("ok")
利用requests模塊自定義請求頭信息,并且發(fā)起帶參數(shù)的get請求
get方法有個headers參數(shù) 把請求頭信息的字典賦給headers參數(shù)
本文的內(nèi)容源自其他博客的總結(jié),結(jié)構(gòu)如下:
HTTP 的請求報文
GET 方法的特點
POST 方法的特點
GET 和 POST 的區(qū)別
首先我們要解決的第一個問題是:GET 和 POST 是什么?
GET 和 POST 其實都是 HTTP 的請求方法。除了這 2 個請求方法之外,HTTP 還有 HEAD、PUT、DELETE、TRACE、CONNECT、OPTIONS 這 6 個請求方法。所以HTTP 的請求方法共計有 8 種,它們的描述如下所示:
接下來我們解決第二個問題:請求方法如何使用?
要解決這個問題,我們首先需要了解 HTTP 的請求報文結(jié)構(gòu):
?可以看到 HTTP 的請求報文由三部分構(gòu)成:
我們通過一個實際的例子來看看 HTTP 的 GET 請求報文是什么樣的,我們這里以訪問 https://api.github.com/search/users?q=JakeWharton 為例,通過抓包我們得到的請求報文如下所示:
GET /search/users?q=JakeWharton HTTP/1.1
Host: api.github.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _octo=GH1.1.1623908978.1549006668; _ga=GA1.2.548087391.1549006688; logged_in=yes; dotcom_user=GoMarck; _gid=GA1.2.17634150.1554639136; _gat=1
我們重點看到請求行:
GET /search/users?q=JakeWharton HTTP/1.1
可以看到請求方法用的是 GET 請求,URL為 /search/users?q=JakeWharton,協(xié)議為 HTTP1.1。
請求行下面部分全都是請求頭部,我們可以看到 host 為 api.github.com,連接方式為長連接等信息。值得注意的是我們這個例子中是不存在請求數(shù)據(jù)的。
接下來我們在來看一下 POST 請求的報文(該例子源自其他博客):
POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
可以看到請求行中請求方法為 POST,URL 為空,協(xié)議版本也是 HTTP1.1。它和上面 GET 方法例子不一樣的地方在于它的請求參數(shù)是位于請求數(shù)據(jù)中的,可以看到 name=Professional%20Ajax&publisher=Wiley 就是它的請求數(shù)據(jù)。并且我們要注意到在請求數(shù)據(jù)和請求頭之間是空出一行的,這是必不可少的。
1、前面的例子:https://api.github.com/search/users?q=JakeWharton 就是一個非常典型的 GET 請求的表現(xiàn)形式,即請求的數(shù)據(jù)會附在 URL 之后(放在請求行中),以 ? 分割 URL 和傳輸數(shù)據(jù),多個參數(shù)用 & 連接。
2、除此之外,根據(jù) HTTP 規(guī)范,GET 用于信息獲取,而且應(yīng)該是安全和冪等的 。
安全性指的是非修改信息,即該操作用于獲取信息而非修改信息。換句話說,GET請求一般不應(yīng)產(chǎn)生副作用,也就是說,它僅僅是獲取資源信息,就像數(shù)據(jù)庫查詢一樣,不會修改,增加數(shù)據(jù),不會影響資源的狀態(tài)。
冪等性 (Idempotence) 則指的是無論調(diào)用這個URL 多少次,都不會有不同的結(jié)果的 HTTP 方法。而在實際過程中,這個規(guī)定沒有那么嚴(yán)格。例如在一個新聞應(yīng)用中,新聞?wù)军c的頭版不斷更新,雖然第二次請求會返回不同的一批新聞,該操作仍然被認(rèn)為是安全的和冪等的,因為它總是返回當(dāng)前的新聞。
3、GET 是會被瀏覽器主動緩存的,如果下一次傳輸?shù)臄?shù)據(jù)相同,那么就會返回緩存中的內(nèi)容,以求更快地展示數(shù)據(jù)。
4、GET 方法的 URL 一般都具有長度限制,但是需要注意的是 HTTP 協(xié)議中并未規(guī)定 GET 請求的長度。這個長度限制主要是由瀏覽器和 Web 服務(wù)器所決定的,并且各個瀏覽器對長度的限制也各不相同。
5、GET 方法只產(chǎn)生一個 TCP 數(shù)據(jù)包,瀏覽器會把請求頭和請求數(shù)據(jù)一并發(fā)送出去,服務(wù)器響應(yīng) 200 ok(返回數(shù)據(jù))。
相關(guān)視頻推薦
c++后臺開發(fā),如何讓你的http web服務(wù)器做的與眾不同
從50道騰訊面試題,分析騰訊c++后端工程的技能樹
學(xué)習(xí)地址:C/C++Linux服務(wù)器開發(fā)/后臺架構(gòu)師【零聲教育】-學(xué)習(xí)視頻教程-騰訊課堂
需要C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料加群812855908獲取(資料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費分享
上面說了那么多 GET 方法和 POST 方法各自的特點,它們在外在的表現(xiàn)上似乎是有著諸多的不同,但是實際上,它們的本質(zhì)是一樣的,并無區(qū)別!!!
這似乎有些不可思議,但是我們重新回想一下 GET 和 POST 是什么?它們是 HTTP 請求協(xié)議的請求方法,而 HTTP 又是基于TCP/IP的關(guān)于數(shù)據(jù)如何在萬維網(wǎng)中如何通信的協(xié)議,所以 GET/POST 實際上都是 TCP 鏈接。
也就是說,GET 和 POST 所做的事其實是一樣的,如果你給 GET 加上請求數(shù)據(jù),給 POST 加上 URL 參數(shù),這在技術(shù)上是完全可行的,事實上確實有一些人為了貪圖方便在更新資源時用了GET,因為用POST必須要到FORM(表單),這樣會麻煩一點(但是強烈不建議這樣子做!!!)。
既然 GET 和 POST 的底層都是 TCP,那么為什么 HTTP 還要特別將它們區(qū)分出來呢?
其實可以想象一下,如果我們直接使用 TCP 進行數(shù)據(jù)的傳輸,那么無論是單純獲取資源的請求還是修改服務(wù)器資源的請求在外觀上看起來都是 TCP 鏈接,這樣就非常不利于進行管理。所以在 HTTP 協(xié)議中,就會對這些不同的請求設(shè)置不同的類別進行管理,例如單純獲取資源的請求就規(guī)定為 GET、修改服務(wù)器資源的請求就規(guī)定為 POST,并且也對它們的請求報文的格式做出了相應(yīng)的要求(例如請求參數(shù) GET 位于 URL 而 POST 則位于請求數(shù)據(jù)中)。
當(dāng)然,如果我們想將 GET 的請求參數(shù)放置在請求數(shù)據(jù)中或者將 POST 的請求數(shù)據(jù)放置在 URL 中,這是完全可以的,雖然這樣子做并不符合 HTTP 的規(guī)范。但是這樣子做是否能得到我們期望的響應(yīng)數(shù)據(jù)呢?答案是未必,這取決于服務(wù)器的行為。
以 GET 方法在請求數(shù)據(jù)中放置請求參數(shù)為例,有些服務(wù)器會將請求數(shù)據(jù)中的參數(shù)讀出,在這種情況下我們依然能獲得我們期望的響應(yīng)數(shù)據(jù);而有些服務(wù)器則會選擇直接忽略,這種情況下我們就無法獲取期望的響應(yīng)數(shù)據(jù)了。
所以,對于 GET 和 POST 的區(qū)別,總結(jié)來說就是:它們的本質(zhì)都是 TCP 鏈接,并無區(qū)別。但是由于 HTTP 的規(guī)定以及瀏覽器/服務(wù)器的限制,導(dǎo)致它們在應(yīng)用過程中可能會有所不同。
首先說一下為什么寫這篇文章,以前寫客戶端的時候,要經(jīng)常調(diào)用后端的接口,一般很多公司的接口,都是統(tǒng)一POST提交方式
服務(wù)端響應(yīng)的是 JSON 格式字符串,方便統(tǒng)一管理,當(dāng)時對POST不太清楚,開始的時候,不覺得有啥
但是真正等到自己寫一個獨立的技術(shù)社區(qū)的時候,也就是 www.helloworld.net ,需要上傳,需要表單提交等
才發(fā)現(xiàn),不懂這些,用到了的時候,很是費勁,很耽誤時間。
下面就當(dāng)是復(fù)習(xí)了,學(xué)習(xí)一下GET , POST 這兩種最常用的提交方式
HTTP 請求方法有9種,分別是
序號 | 方法 | 描述 |
1 | GET | 請求指定的頁面信息,并返回實體主體。 |
2 | HEAD | 類似于 GET 請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報頭 |
3 | POST | 向指定資源提交數(shù)據(jù)進行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中。POST 請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改。 |
4 | PUT | 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。 |
5 | DELETE | 請求服務(wù)器刪除指定的頁面。 |
6 | CONNECT | HTTP/1.1 協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。 |
7 | OPTIONS | 允許客戶端查看服務(wù)器的性能。 |
8 | TRACE | 回顯服務(wù)器收到的請求,主要用于測試或診斷。 |
9 | PATCH | 是對 PUT 方法的補充,用來對已知資源進行局部更新 。 |
最常用的還是 GET , POST
我們知道,http是一個通信協(xié)議,啥叫通信協(xié)議,通信嘛,就是兩個人要溝通,協(xié)議嘛,就是怎么溝通
比如我說A,你知道我餓了想吃東西了,我再說 A 米飯, 你就知道我餓了,并且想吃米飯了。
對的,協(xié)議就是雙方提前商量好的溝通的內(nèi)容的格式
HTTP通信協(xié)議就是 HTTP客戶端和HTTP服務(wù)端 雙方規(guī)定好的格式
那么這個HTTP消息,有哪幾部分組成呢
很簡單,HTTP消息包含兩部分
比如我們在瀏覽器中發(fā)一個請求www.helloworld.net 回車,此時我們發(fā)的是GET請求
那么請求頭是:
GET / HTTP/2
Host: www.helloworld.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: Hm_lvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668406379; Hm_lpvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668406379
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
If-None-Match: "d696-1nnZwKI6/LZalqvEzQx9IFil/tw"
TE: trailers
注意: HTTP 的GET請求,是沒有請求體的,這也就是為什么有些公司統(tǒng)一封裝請求為POST,而不是GET的原因了
因為POST是有請求體的,可以帶大量的數(shù)據(jù),GET因為沒有請求體,攜帶參數(shù)只能放在URL中,能帶的數(shù)據(jù)量是比較少的。
GET 訪求方法最常用,也是最簡單的一種,像其語義一樣,GET 就是獲取文件的意思
所以GET請求就是獲取服務(wù)器上的某個資源 ,使用也很簡單,我們記住下面兩點就行了
服務(wù)器收到請求就可以解析出來url后面帶的參數(shù)了,name=tom , age=23
下面我們重點看一下POST請求
POST 是提交的意思,如果我們需要向服務(wù)器提交一些數(shù)據(jù),就可以使用POST方法
雖然POST是提交的意思,協(xié)議規(guī)定的也是用POST提交數(shù)據(jù),但是現(xiàn)在很多公司并沒有這樣搞
查詢也會用POST,其實它只是個單詞,服務(wù)端收到 請求后,是查詢資源,還是刪除資源,還是提交
都可以的,只是看你們公司前后端怎么規(guī)定即可。
下面我們看看POST有哪幾種提交數(shù)據(jù)的方式
這也是POST默認(rèn)的一種方式 ,對應(yīng)的請求頭中的 Content-Type 為 application/x-www-form-urlencoded
我們從瀏覽器中抓取www.helloworld.net 上的幾個請求方式,為例,如下
## 請求頭
POST /v1/special/getSpecialCateList HTTP/2
Host: tiger-api.helloworld.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Authorization:
token:
ts: 1668407094
sign: d41d8cd98f00b204e9800998ecf8427e
deviceType: pc
Origin: https://www.helloworld.net
Connection: keep-alive
Referer: https://www.helloworld.net/
Cookie: Hm_lvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668406379; Hm_lpvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668406398
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Content-Length: 0
## 請求體
action=10&pageNum=1&pageSize=10&uuid=15139897
此種方式,一般是提交key, value 的值。
我之前把這種當(dāng)作了上面的那種,后來寫文件上傳的時候,查了一下,原來 不是
這種提交方法一般是上傳文件用的多。通常是用在客戶端向服務(wù)端傳送大文件數(shù)據(jù),如:圖片或者文件。
首先來解釋下什么它的編碼方式,首先會生成一個很長的 boundary 字符串分界線,表明下面的都是表單內(nèi)容,然后緊接著跟的是表單中的第一個鍵值對中的名稱,而后一個換行,跟著值。然后再生成一個boundary 字符串分界線,用于分割不同的鍵值。之后就重復(fù)以上操作,詳細(xì)的流程請看下方的例子。
同樣我們以 www.helloworld.net 舉例,我們從里面找個接口,抓取一下,看看
# 請求頭
POST http://www.helloworld.net/xyz HTTP/1.1
Host: www.helloworld.net
User-Agent: python-requests/2.24.0
Accept-Encoding: gzip, deflate
Accept: */*
Content-Type: multipart/form-data; boundary=e42346452as650adf2345fadade
Content-Length: 222
Connection: keep-alive
# 請求體
--e42346452as650adf2345fadade
Content-Disposition: form-data; name="field0"
value1
--e42346452as650adf2345fadade
Content-Disposition: form-data; name="field1"
value2
--e42346452as650adf2345fadade--
Content-Disposition: form-data; name="field2"; filename="filename"
Content-Type: text/plain
--e42346452as650adf2345fadade--
從上面我們可以知道,在請求頭中的 Content-Type中,有一個 boundary=e42346452as650adf2345fadade
這個boundary后面的字符串都是隨機生成的。用于請求體中數(shù)據(jù)的分段的。
其實就是個分隔符的作用。
這種就是我們現(xiàn)在用的最多的了,而且也非常方便
在請求頭中設(shè)置 content-type=application/json,就表明請求體中的內(nèi)容格式為json格式
同樣的,服務(wù)端在響應(yīng)的時候,順應(yīng)頭中也會添加一個 content-type=application/json
同樣的也是告訴客戶端,我響應(yīng)給你的響應(yīng)體中的內(nèi)容,格式同樣為 json 格式
同的樣我們也參照 www.helloworld.net 中的一個請求,如下
## 請求頭
POST /v1/special/getSpecialList HTTP/2
Host: tiger-api.helloworld.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Authorization:
token:
ts: 1668408188
sign: 08fab32346193fa92037b5ca5f9ed592
deviceType: pc
Content-Length: 30
Origin: https://www.helloworld.net
Connection: keep-alive
Referer: https://www.helloworld.net/
Cookie: Hm_lvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668406379,1668408042,1668408051; Hm_lpvt_c7e77fd22dddf4a169b8d6f4807c5a4c=1668408051
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
TE: trailers
## 請求體
action=10&pageNum=1&sortType=0
我們看一下響應(yīng)體:
{
"code": 1,
"data": {
"hasMore": false,
"list": [
{
"uuid": "5441523000",
"title": "區(qū)塊鏈原理和應(yīng)用",
"totalCount": 0,
"chapterCount": 1,
"readCount": 0,
"subscribeCount": 1,
"createTime": "0001-01-01T00:00:00Z",
"status": 0,
"profile": "1037883613",
"nicker": "小天",
"avatar": "https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/d04d513fbea19f6cb7c3b4beee3c7f5e.jfif",
"subscribed": false
},
{
"uuid": "bbatgp",
"title": "C語言編程(初級)",
"totalCount": 0,
"chapterCount": 19,
"readCount": 2938,
"subscribeCount": 1,
"createTime": "0001-01-01T00:00:00Z",
"status": 0,
"profile": "80662724",
"nicker": "Suzhou",
"avatar": "https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/d04d513fbea19f6cb7c3b4beee3c7f5e.jfif",
"subscribed": false
}
]
},
"message": "獲取數(shù)據(jù)成功",
"errMessage": ""
}
這個一直沒有遇到過,很少用
其實就是請求消息中,請求體中的內(nèi)容格式是純文本xml格式
此種我們就不作介紹
有興趣的可以下面自己查資料
綜上所述,HTTP 的POST四種方法以及GET的簡單介紹,我們總結(jié)如下:
1. `application/x-www-form-urlencoded` , 也是默認(rèn)的方式,主要提交的數(shù)據(jù)是key, value 形式的
2. `multipart/form-data` ,此種方式 是客戶端向服務(wù)端提交大數(shù)據(jù)用的,一般上傳文件等用到。
? 注意這種方式,會在請求頭中生成一個boundary字段,其對應(yīng)的值是一個隨機生成的字符串,用于分隔請求體中的數(shù)據(jù)用的
簡單的介紹了一下HTTP的GET,POST的一些知識,希望對你們有用。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。