成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python解析multipart boundary:aiohttp與requests文件上傳詳解

開發(fā) 前端
本文詳細(xì)介紹了multipart/form-data中boundary的作用,并對(duì)Python中requests與aiohttp兩種HTTP請(qǐng)求庫在處理boundary時(shí)的自動(dòng)與手動(dòng)構(gòu)造方式進(jìn)行了深入解析。

目錄

1. 什么是boundary?

2. requests庫中boundary的處理

? 2.1 自動(dòng)處理boundary

? 2.2 手動(dòng)設(shè)置 boundary

? 2.3 手動(dòng)構(gòu)建boundary

3. aiohttp庫中boundary的處理

        ? 3.1 自動(dòng)處理boundary

        ? 3.2 手動(dòng)設(shè)置 boundary

         ? 3.3 手動(dòng)構(gòu)建boundary

 4. aiohttp與requests的優(yōu)缺點(diǎn)對(duì)比

 5. 總結(jié)

 6. 相關(guān)閱讀

1. 什么是boundary?

在HTTP協(xié)議中,當(dāng)我們使用multipart/form-data提交表單時(shí),整個(gè)請(qǐng)求體包含多個(gè)部分,每部分之間的邊界由一個(gè)稱為boundary的字符串分隔。例如,HTTP請(qǐng)求頭中可能包含如下內(nèi)容:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

這個(gè)boundary字符串保證服務(wù)器能夠正確解析各個(gè)字段和文件內(nèi)容,是構(gòu)造復(fù)雜表單數(shù)據(jù)的重要組成部分。

2. requests庫中boundary的處理

2.1 自動(dòng)處理boundary

使用requests發(fā)送表單數(shù)據(jù)時(shí),只需要將文件或字段通過files和data參數(shù)傳遞,requests會(huì)自動(dòng)生成boundary并封裝數(shù)據(jù)。

import requests

# 目標(biāo)URL(測(cè)試用:httpbin.org可返回提交的數(shù)據(jù))
url = 'http://httpbin.org/post'

# 構(gòu)造文件上傳數(shù)據(jù):requests會(huì)自動(dòng)構(gòu)造multipart/form-data請(qǐng)求
files = {
    # 第一個(gè)參數(shù)為字段名稱,元組中依次為:(文件名, 文件對(duì)象, MIME類型)
    'file':('test.txt', open('test.txt', 'rb'), 'text/plain')
}

# 發(fā)送POST請(qǐng)求
response = requests.post(url, files=files)

# 打印服務(wù)器返回內(nèi)容
print(response.text)

注釋說明:

? 此示例中,requests自動(dòng)在請(qǐng)求頭中生成Content-Type及其中的boundary,無需開發(fā)者手動(dòng)干預(yù)。

? 適用于大部分常規(guī)使用場(chǎng)景。

2.2 手動(dòng)設(shè)置 Boundary

在某些特殊情況下,可能需要手動(dòng)指定 boundary。此時(shí)可以借助 requests-toolbelt 庫中的 MultipartEncoder。

首先需安裝 requests-toolbelt:

pip install requests-toolbelt

下面是手動(dòng)指定 boundary 的示例代碼:

from requests_toolbelt.multipart.encoder import MultipartEncoder
import requests

def send_formdata_manual():
    url = 'http://httpbin.org/post'
    # 自定義 boundary 字符串
    boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
    # 使用 MultipartEncoder 構(gòu)造 multipart 數(shù)據(jù),同時(shí)指定 boundary
    encoder = MultipartEncoder(
        fields={
            'field1': 'value1',
            'file': ('test.txt', open('test.txt', 'rb'), 'text/plain')
        },
        boundary=boundary
    )
    # 設(shè)置 Content-Type 頭,包含自定義的 boundary
    headers = {'Content-Type': encoder.content_type}
    # 發(fā)送 POST 請(qǐng)求
    response = requests.post(url, data=encoder, headers=headers)
    print("手動(dòng)設(shè)置 boundary 的響應(yīng):", response.text)

send_formdata_manual()

2.3 手動(dòng)構(gòu)建boundary

有時(shí)我們需要對(duì)請(qǐng)求體的格式進(jìn)行更精細(xì)的控制,此時(shí)可以選擇手動(dòng)構(gòu)建multipart/form-data格式的數(shù)據(jù)。

import requests

# 目標(biāo)URL
url = 'http://httpbin.org/post'

# 自定義boundary字符串
boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'

# 構(gòu)造請(qǐng)求體各部分?jǐn)?shù)據(jù),注意各部分之間以boundary分隔
data_lines = []
# 添加第一個(gè)字段:普通文本字段
data_lines.append('--' + boundary)
data_lines.append('Content-Disposition: form-data; name="field1"')
data_lines.append('')  # 空行分隔頭與內(nèi)容
data_lines.append('value1')

# 添加第二個(gè)字段:文件字段
data_lines.append('--' + boundary)
data_lines.append('Content-Disposition: form-data; name="file"; filename="test.txt"')
data_lines.append('Content-Type: text/plain')
data_lines.append('')
# 讀取文件內(nèi)容(確保當(dāng)前目錄下有test.txt文件)
with open('test.txt', 'r', encoding='utf-8') as f:
    data_lines.append(f.read())

# 結(jié)束標(biāo)志:加上結(jié)尾的boundary標(biāo)記
data_lines.append('--' + boundary + '--')

# 將各部分用CRLF連接
body = '\r\n'.join(data_lines)

# 構(gòu)造請(qǐng)求頭,指明Content-Type及boundary
headers = {
    'Content-Type': 'multipart/form-data; boundary=' + boundary
}

# 發(fā)送POST請(qǐng)求,此處需要將body轉(zhuǎn)換為字節(jié)串
response = requests.post(url, data=body.encode('utf-8'), headers=headers)
print(response.text)

注釋說明:

? 手動(dòng)構(gòu)造的流程:先定義好boundary,再將每個(gè)部分的數(shù)據(jù)按照標(biāo)準(zhǔn)格式拼接(包括Content-Disposition和Content-Type等)。

? 最后將拼接好的字符串通過encode('utf-8')轉(zhuǎn)為字節(jié)發(fā)送。

3. aiohttp庫中boundary的處理

3.1 自動(dòng)處理boundary

aiohttp作為異步HTTP庫,同樣支持通過aiohttp.FormData構(gòu)造multipart/form-data數(shù)據(jù),并自動(dòng)管理boundary。

import aiohttp
import asyncio

async def main():
    url = 'http://httpbin.org/post'
    # 使用aiohttp提供的FormData構(gòu)造表單數(shù)據(jù)
    form = aiohttp.FormData()
    form.add_field('field1', 'value1')
    # 添加文件字段,注意以二進(jìn)制方式打開文件
    form.add_field('file',
                   open('test.txt', 'rb'),
                   filename='test.txt',
                   content_type='text/plain')
    
    # 使用異步上下文管理器發(fā)送請(qǐng)求
    async with aiohttp.ClientSession() as session:
        async with session.post(url, data=form) as resp:
            print(await resp.text())

# 運(yùn)行異步任務(wù)
asyncio.run(main())

注釋說明:

? aiohttp.FormData會(huì)自動(dòng)生成適合的boundary,并構(gòu)造請(qǐng)求體。

? 異步寫法適合高并發(fā)或異步應(yīng)用場(chǎng)景。

3.2 手動(dòng)設(shè)置 Boundary

有時(shí)需要自定義 boundary,比如為了和服務(wù)端進(jìn)行特殊交互,此時(shí)可以使用 aiohttp.MultipartWriter 手動(dòng)構(gòu)造 multipart 數(shù)據(jù)。

import aiohttp
import asyncio

async def send_formdata_manual():
    # 自定義 boundary 字符串(注意確保不會(huì)與數(shù)據(jù)內(nèi)容沖突)
    boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
    # 創(chuàng)建 MultipartWriter 對(duì)象,手動(dòng)指定 boundary
    mp_writer = aiohttp.MultipartWriter(boundary=boundary)
    
    # 添加普通字段
    part1 = mp_writer.append('value1')
    part1.set_content_disposition('form-data', name='field1')
    
    # 添加文件字段
    with open('test.txt', 'rb') as f:
        part2 = mp_writer.append(f.read(), {'Content-Type': 'text/plain'})
        part2.set_content_disposition('form-data', name='file', filename='test.txt')
    
    # 發(fā)送 POST 請(qǐng)求
    async with aiohttp.ClientSession() as session:
        async with session.post('http://httpbin.org/post', data=mp_writer) as resp:
            result = await resp.text()
            print("手動(dòng)設(shè)置 boundary 的響應(yīng):", result)

# 運(yùn)行異步任務(wù)
asyncio.run(send_formdata_manual())

代碼說明:

? 使用 aiohttp.MultipartWriter 手動(dòng)構(gòu)造 multipart 數(shù)據(jù),并通過參數(shù) boundary 指定自定義分隔符。

? 每個(gè)字段使用 append 方法添加,并通過 set_content_disposition 設(shè)置字段名稱與文件信息。

? 通過 aiohttp 異步發(fā)送請(qǐng)求,觀察服務(wù)端對(duì)自定義 boundary 的處理結(jié)果。

3.3 手動(dòng)構(gòu)建boundary

與requests類似,aiohttp也支持手動(dòng)構(gòu)造請(qǐng)求體,適用于需要完全自定義請(qǐng)求體格式的場(chǎng)景。

import aiohttp
import asyncio

async def main():
    url = 'http://httpbin.org/post'
    
    # 自定義boundary
    boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
    parts = []
    # 添加普通文本字段
    parts.append('--' + boundary)
    parts.append('Content-Disposition: form-data; name="field1"')
    parts.append('')
    parts.append('value1')
    
    # 添加文件字段
    parts.append('--' + boundary)
    parts.append('Content-Disposition: form-data; name="file"; filename="test.txt"')
    parts.append('Content-Type: text/plain')
    parts.append('')
    with open('test.txt', 'r', encoding='utf-8') as f:
        parts.append(f.read())
    
    # 結(jié)束標(biāo)記
    parts.append('--' + boundary + '--')
    
    # 構(gòu)造完整請(qǐng)求體
    body = '\r\n'.join(parts)
    headers = {
        'Content-Type': 'multipart/form-data; boundary=' + boundary
    }
    
    async with aiohttp.ClientSession() as session:
        async with session.post(url, data=body.encode('utf-8'), headers=headers) as resp:
            print(await resp.text())

asyncio.run(main())

注釋說明:

? 手動(dòng)構(gòu)造流程與requests類似,需自行拼接各部分?jǐn)?shù)據(jù)和boundary。

? 注意在異步環(huán)境中,通過await獲取響應(yīng)數(shù)據(jù)。

4. aiohttp與requests的優(yōu)缺點(diǎn)對(duì)比

特性

requests

aiohttp

同步/異步

同步,適合簡單腳本及同步流程

異步,適合高并發(fā)、大規(guī)模請(qǐng)求場(chǎng)景

易用性

API設(shè)計(jì)直觀、簡單易用,自動(dòng)處理multipart表單數(shù)據(jù)

API設(shè)計(jì)靈活,適合異步編程,但學(xué)習(xí)曲線稍陡

性能

在低并發(fā)場(chǎng)景下表現(xiàn)良好,但阻塞I/O可能導(dǎo)致性能瓶頸

利用異步機(jī)制高效處理并發(fā)請(qǐng)求,性能優(yōu)勢(shì)明顯

手動(dòng)構(gòu)造支持

允許手動(dòng)構(gòu)造請(qǐng)求體,適用于對(duì)請(qǐng)求數(shù)據(jù)精細(xì)控制的需求

同樣支持手動(dòng)構(gòu)造,但通常建議使用內(nèi)置FormData自動(dòng)處理

社區(qū)與文檔

社區(qū)成熟,文檔詳細(xì),示例豐富

社區(qū)活躍,文檔逐步完善,但部分高級(jí)用法可能需要參考源碼

注釋說明:

? 如果項(xiàng)目對(duì)并發(fā)和性能有較高要求,aiohttp無疑是更好的選擇;

? 對(duì)于多數(shù)普通應(yīng)用,requests的簡單易用更能提高開發(fā)效率。

5. 總結(jié)

本文詳細(xì)介紹了multipart/form-data中boundary的作用,并對(duì)Python中requests與aiohttp兩種HTTP請(qǐng)求庫在處理boundary時(shí)的自動(dòng)與手動(dòng)構(gòu)造方式進(jìn)行了深入解析。通過完整的代碼示例,你可以看到兩者在實(shí)際應(yīng)用中的實(shí)現(xiàn)細(xì)節(jié)及各自的優(yōu)缺點(diǎn)。無論是同步的requests還是異步的aiohttp,都能滿足大部分場(chǎng)景的需求,而如何選擇則應(yīng)基于具體項(xiàng)目需求和性能要求。


責(zé)任編輯:武曉燕 來源: 不止于python
相關(guān)推薦

2009-07-16 17:26:11

WebWork文件上傳

2009-07-21 15:38:31

2024-01-23 09:02:35

PyYAML庫PythonYAML

2009-11-24 15:01:59

PHP通用文件上傳類

2009-07-24 15:07:56

ASP.NET上傳文件

2017-12-01 10:13:42

前端操作上傳

2009-08-03 17:22:15

JSON解析

2010-03-17 14:42:09

Python 文件

2012-06-13 02:02:43

ServletJavaJSP

2018-11-30 09:30:46

aiohttp爬蟲Python

2019-10-18 09:36:17

Oracle數(shù)據(jù)庫硬解析

2010-03-17 15:01:24

Python復(fù)制文件

2024-04-15 13:13:04

PythonJSON

2024-03-14 10:51:13

服務(wù)器技術(shù).NET Core

2010-09-16 15:17:33

2025-01-15 09:04:50

SPCXBar樣本均值

2019-08-29 23:02:24

Python解析式表達(dá)列

2016-12-15 08:28:34

HttpURLConn上傳文件

2021-07-05 12:09:58

Python編程語言

2013-11-29 15:41:08

解析漏洞ApacheApache解析漏洞
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 99精品国自产在线 | 一本大道久久a久久精二百 欧洲一区二区三区 | 亚洲欧美一区二区三区国产精品 | 亚洲精品在线观 | 日韩有码一区 | h片在线观看网站 | 欧美精品综合在线 | 亚洲综合二区 | 国产在线视频在线观看 | 日韩欧美三级电影在线观看 | 国产成人自拍av | a视频在线观看 | 亚洲一一在线 | 国产一区二区视频在线 | 成年无码av片在线 | 一区二区三区四区免费视频 | 日韩欧美一区二区三区四区 | 亚洲国产精品一区在线观看 | 91网在线观看 | 中文字幕亚洲欧美日韩在线不卡 | 台湾av在线 | 日韩成人精品一区二区三区 | 国产欧美精品在线观看 | 麻豆视频国产在线观看 | 皇色视频在线 | 国产清纯白嫩初高生在线播放视频 | 亚洲影视在线 | 91视频.| 天天综合天天 | 在线看91| 久久精片 | 国产欧美精品区一区二区三区 | 国户精品久久久久久久久久久不卡 | 亚洲永久字幕 | 精品国产一二三区 | 中文字幕成人网 | 亚洲欧美视频一区 | 天堂av在线影院 | 中文字幕视频网 | 天天干干| 欧美激情五月 |