欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Python中httptools模塊的使用

 更新時(shí)間:2023年03月03日 09:48:45   作者:古明地覺  
httptools?是一個(gè)?HTTP?解析器,它首先提供了一個(gè)?parse_url?函數(shù),用來解析?URL。這篇文章就來和大家聊聊它的用法吧,感興趣的可以了解一下

如果你用過 FastAPI 的話,那么你一定知道 uvicorn,它是一個(gè)基于 uvloop 和 httptools 實(shí)現(xiàn)的高性能 ASGI 服務(wù)器。

其中 uvloop 采用 Cython 編寫,用于替換 asyncio 中的事件循環(huán),可以讓 asyncio 速度增加 2 到 4 倍。而 httptools 是基于 C 語言實(shí)現(xiàn)的 HTTP 解析器,用來解析 HTTP 請求的。

本次就來聊一聊 httptools 這個(gè)模塊的詳細(xì)用法,至于 uvloop、uvicorn 等相關(guān)內(nèi)容,后續(xù)我會(huì)一點(diǎn)一點(diǎn)補(bǔ)充上去,并從源碼的角度全給說明白(挖了個(gè)坑)。

httptools 是一個(gè) HTTP 解析器,它首先提供了一個(gè) parse_url 函數(shù),用來解析 URL。

import?httptools

#?第一個(gè)參數(shù)必須是?bytes?對象
url?=?httptools.parse_url(
????b"http://www.baidu.com"
)
#?返回一個(gè)?URL?對象
print(url.__class__)
"""
<class?'httptools.parser.parser.URL'>
"""

那么這個(gè) URL 對象有哪些屬性呢?

通過源碼可知,總共有七個(gè)屬性,我們來測試一下。

import?httptools

#?第一個(gè)參數(shù)是?bytes?對象
url?=?b"http://satori:123456@www.baidu.com:80/s?wd=koishi#flag"
url_obj?=?httptools.parse_url(url)

print("協(xié)議:",?url_obj.schema)
print("IP:",?url_obj.host)
print("端口:",?url_obj.port)
print("路徑:",?url_obj.path)
print("查詢參數(shù):",?url_obj.query)
print("錨點(diǎn):",?url_obj.fragment)
print("用戶信息:",?url_obj.userinfo)
"""
協(xié)議:?b'http'
IP:?b'www.baidu.com'
端口:?80
路徑:?b'/s'
查詢參數(shù):?b'wd=koishi'
錨點(diǎn):?b'flag'
用戶信息:?b'satori:123456'
"""

比較簡單,如果參數(shù)不符合 URL 的標(biāo)準(zhǔn)格式,那么會(huì)拋出 HttpParserInvalidURLError 錯(cuò)誤。

然后是 HTTP 請求報(bào)文和響應(yīng)報(bào)文的解析,因?yàn)閳?bào)文只是一坨字節(jié)流,需要將它解析成某個(gè) Request 對象或 Response 對象,而 httptools 就是干這件事情的。

首先來看一下報(bào)文格式,請求報(bào)文如下:

接下來是響應(yīng)報(bào)文:

所以無論是請求報(bào)文還是響應(yīng)報(bào)文,都由 起始行 + 請求頭/響應(yīng)頭 + 請求體/響應(yīng)體 組成。而我們在拿到原始的報(bào)文之后,也可以很方便地進(jìn)行解析,從圖中可以看出最后一個(gè) Header 字段和響應(yīng)體之間有兩個(gè)換行,而換行用 \r\n 表示。因此我們只要按照 "\r\n\r\n" 進(jìn)行 split 即可,會(huì)得到一個(gè)數(shù)組,數(shù)組的第二個(gè)元素就是請求體/響應(yīng)體,第一個(gè)元素就是起始行 + 請求頭/響應(yīng)頭。

然后對數(shù)組的第一個(gè)元素按照 "\r\n" 再進(jìn)行 split,又可以得到一個(gè)數(shù)組,該數(shù)組的第一個(gè)元素就是起始行,剩余的元素就是請求頭/響應(yīng)頭。

所以我們在拿到報(bào)文之后,完全可以自己手動(dòng)解析,但 httptools 是用 C 實(shí)現(xiàn)的,所以速度會(huì)快一些,但干的事情是一樣的。下面來看看 httptools 如何解析請求報(bào)文:

from?pprint?import?pprint
import?httptools

#?請求報(bào)文
request_payload?=?b"""POST?/index?a=1?HTTP/1.1
Host:?localhost:8080
Connection:?keep-alive
Content-Length:?26
Cache-Control:?max-age=0
Upgrade-Insecure-Requests:?1
Accept:?text/html
Accept-Encoding:?gzip,?deflate,?sdch
Cookie:?_octo=GH1.1.1989111283.1493917476;?logged_in=yes

{"name":"satori","age":17}"""

class?Request:
????"""
????將請求報(bào)文的解析結(jié)果封裝成?Request?對象
????"""
????def?__init__(self):
????????self.headers?=?{}
????????self.body?=?b""
????????self.path?=?None

????def?on_url(self,?path:?bytes):
????????self.path?=?path

????def?on_header(self,?name:?bytes,?value:?bytes):
????????self.headers[name]?=?value

????def?on_body(self,?body:?bytes):
????????self.body?=?body

#?實(shí)例化?Request?對象
request?=?Request()
#?將?request?作為參數(shù)傳到?HttpRequestParser?中
parser?=?httptools.HttpRequestParser(request)
#?傳入請求報(bào)文,進(jìn)行解析
parser.feed_data(request_payload)

#?獲取?HTTP?版本
print(parser.get_http_version())
"""
1.1
"""
#?是否是長鏈接(Connection?指定為?keep-alive)
print(parser.should_keep_alive())
"""
True
"""
#?獲取請求方法
print(parser.get_method())
"""
b'POST'
"""
#?以上幾個(gè)都是?HttpRequestParser?對象的方法

#?獲取路徑
print(request.path)
"""
b'/index?a=1'
"""

#?獲取請求頭
pprint(request.headers)
"""
{b'Accept':?b'text/html',
?b'Accept-Encoding':?b'gzip,?deflate,?sdch',
?b'Cache-Control':?b'max-age=0',
?b'Connection':?b'keep-alive',
?b'Content-Length':?b'26',
?b'Cookie':?b'_octo=GH1.1.1989111283.1493917476;?logged_in=yes',
?b'Host':?b'localhost:8080',
?b'Upgrade-Insecure-Requests':?b'1'}
"""
#?Cookie?也是請求頭的一部分,但在解析的時(shí)候會(huì)單獨(dú)拿出來
#?再解析成一個(gè)字典,然后通過?request.cookies?獲取

#?獲取請求體
print(request.body)
"""
b'{"name":"satori","age":17}'
"""

以上就是請求報(bào)文的解析,再來看看響應(yīng)報(bào)文。

from?pprint?import?pprint
import?httptools

#?響應(yīng)報(bào)文
response_payload?=?b"""HTTP/1.1?200?OK
Server:?TornadoServer/6.1
Content-Type:?text/html;?charset=UTF-8
Date:?Sun,?22?May?2022?17:54:11?GMT
Content-Length:?21

name:?satori,?age:?17"""

class?Response:
????"""
????將響應(yīng)報(bào)文的解析結(jié)果封裝成?Response?對象
????"""
????def?__init__(self):
????????self.headers?=?{}
????????self.body?=?b""
????????self.status?=?b""

????def?on_header(self,?name:?bytes,?value:?bytes):
????????self.headers[name]?=?value

????def?on_body(self,?body:?bytes):
????????self.body?=?body

????def?on_status(self,?status:?bytes):
????????self.status?=?status

#?實(shí)例化?Response?對象
response?=?Response()
#?將?response?作為參數(shù)傳到?HttpResponseParser?中
parser?=?httptools.HttpResponseParser(response)
#?傳入響應(yīng)報(bào)文,進(jìn)行解析
parser.feed_data(response_payload)

#?獲取?HTTP?版本
print(parser.get_http_version())
"""
1.1
"""
#?是否是長鏈接(不指定?Connection,默認(rèn)為長連接)
print(parser.should_keep_alive())
"""
True
"""
#?獲取狀態(tài)碼
print(parser.get_status_code())
"""
b'OK'
"""

#?獲取狀態(tài)碼對應(yīng)的描述
print(response.status)
"""
b'OK'
"""

#?獲取響應(yīng)頭
pprint(response.headers)
"""
{b'Content-Length':?b'21',
?b'Content-Type':?b'text/html;?charset=UTF-8',
?b'Date':?b'Sun,?22?May?2022?17:54:11?GMT',
?b'Server':?b'TornadoServer/6.1'}
"""

#?獲取響應(yīng)體
print(response.body)
"""
b'name:?satori,?age:?17'
"""

以上就是請求報(bào)文和響應(yīng)報(bào)文的解析,但如果你不是手動(dòng)發(fā)送 TCP 請求的話,那么該模塊基本用不到。因?yàn)閷τ谌魏我粋€(gè)成熟的模塊而言,都具備了報(bào)文解析功能。像 requests, httpx, aiohttp 等等,以及一些 web 框架,它們在拿到報(bào)文之后會(huì)自動(dòng)解析成某個(gè)對象,我們直接通過指定的屬性獲取即可。

而 httptools 便是 uvicorn 的報(bào)文解析器,我們在使用 uvicorn 的時(shí)候,uvicorn 內(nèi)部也會(huì)自動(dòng)通過 httptools 將報(bào)文解析好,而不需要我們手動(dòng)解析。

因此這里介紹的 httptools 了解一下即可,我們只需要知道它是基于 C 實(shí)現(xiàn)的,性能非常高就行。但我們不會(huì)手動(dòng)使用它,而是在使用某個(gè)框架(uvicorn)的時(shí)候,由框架自動(dòng)幫我們將報(bào)文解析好。

到此這篇關(guān)于詳解Python中httptools模塊的使用的文章就介紹到這了,更多相關(guān)Python httptools模塊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python?Flask框架實(shí)現(xiàn)小紅書圖片無水印解析下載

    Python?Flask框架實(shí)現(xiàn)小紅書圖片無水印解析下載

    這篇文章主要為大家介紹了Python?Flask框架實(shí)現(xiàn)小紅書圖片無水印解析下載,需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Python中的嵌套循環(huán)詳情

    Python中的嵌套循環(huán)詳情

    這篇文章主要介紹了Python中的嵌套循環(huán)詳情,嵌套循環(huán)就是一個(gè)外循環(huán)的主體部分是一個(gè)內(nèi)循環(huán)。內(nèi)循環(huán)或外循環(huán)可以是任何類型,下列詳情介紹內(nèi)容,需要的朋友可以參考一下
    2022-03-03
  • centos6.8安裝python3.7無法import _ssl的解決方法

    centos6.8安裝python3.7無法import _ssl的解決方法

    這篇文章主要介紹了centos6.8安裝python3.7無法import _ssl的解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • Python3中簡單的文件操作及兩個(gè)簡單小實(shí)例分享

    Python3中簡單的文件操作及兩個(gè)簡單小實(shí)例分享

    文件操作是我們?nèi)粘T谑褂胮ython的時(shí)候經(jīng)常會(huì)用到的,下面這篇文章主要給大家介紹了關(guān)于Python3中簡單的文件操作及兩個(gè)簡單小實(shí)例的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-06-06
  • 淺析python 定時(shí)拆分備份 nginx 日志的方法

    淺析python 定時(shí)拆分備份 nginx 日志的方法

    本文給大家分享python 定時(shí)拆分備份 nginx 日志的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-04-04
  • python之broadcast和numpy.sum()函數(shù)用法及說明

    python之broadcast和numpy.sum()函數(shù)用法及說明

    這篇文章主要介紹了python之broadcast和numpy.sum()函數(shù)用法及說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Python OpenCV高斯金字塔與拉普拉斯金字塔的實(shí)現(xiàn)

    Python OpenCV高斯金字塔與拉普拉斯金字塔的實(shí)現(xiàn)

    這篇文章主要介紹了Python OpenCV高斯金字塔與拉普拉斯金字塔的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 基于Python實(shí)現(xiàn)通過微信搜索功能查看誰把你刪除了

    基于Python實(shí)現(xiàn)通過微信搜索功能查看誰把你刪除了

    這篇文章主要介紹了基于Python實(shí)現(xiàn)微信搜索查看誰把你刪除了的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • 一篇文章帶你順利通過Python OpenCV入門階段

    一篇文章帶你順利通過Python OpenCV入門階段

    這篇文章主要介紹了Python OpenCV的知識(shí)體系,文章中涉及到的知識(shí)點(diǎn)很多,需要了解這方面知識(shí)的小伙伴可以慢慢理解,慢慢學(xué)習(xí)
    2021-08-08
  • Python中生成器和迭代器的區(qū)別詳解

    Python中生成器和迭代器的區(qū)別詳解

    這篇文章主要介紹了Python中生成器和迭代器的區(qū)別詳解,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02

最新評論