Python

Python 使用 HTTPX 建立 HTTP 請求教學與範例

本篇介紹如何在 Python 中使用 HTTPX 這個 HTTP client 模組,建立各種的 HTTP 請求,下載網頁資料。

HTTPX 是一個 Python 3 的多功能 HTTP client 模組,提供了同步(sync)與非同步(async)的 API 介面,支援 HTTP/1.1 與 HTTP/2,可以用來開發各種 HTTP 通訊相關的應用程式。

安裝 HTTPX

若要安裝 HTTPX 基本的 Python 3 模組,可以執行:

# 安裝基本 HTTPX 模組
pip install httpx

若需要使用到 HTTP/2 協定,可議加裝 http2 這個額外功能(extra):

# 安裝 HTTPX 模組(包含 HTTP/2 協定支援)
pip install httpx[http2]

若需要解開 brotli 壓縮格式的資料,則可加裝 brotli 額外功能:

# 安裝 HTTPX 模組(包含 brotli 解碼器)
pip install httpx[brotli]

發送 HTTP 請求

若要發送 GET 請求,可以使用 httpx.get 函數:

import httpx

# 送出 GET 請求
r = httpx.get('https://httpbin.org/json')

# 判斷是否成功取得網頁內容
if r.is_success:
    # 取得原始文字內容
    text = r.text
	
    # 將 JSON 資料轉為 Python 物件
    jsonObj = r.json()
else:
    # 取得 HTTP Status Code
    statusCode = r.status_code
    print(f"Error: {statusCode}")

取得回應之後,可以使用 is_success 判斷是否成功取得網頁內容,正常狀況下我們可以從回應的物件 r 中以 text 屬性取得原始文字的內容,若確定資料內容為 JSON 格式的話,也可以直接用 json() 函數將資料轉為 Python 的物件。若出現問題時可檢查 HTTP 回應的 status code,依照 status code 來判斷問題並尋找解決方式。

除了 GET 請求之外,其他各種 HTTP 請求也都有對應的函數:

# POST 請求
r = httpx.post('https://httpbin.org/post', data={'key': 'value'})

# PUT 請求
r = httpx.put('https://httpbin.org/put', data={'key': 'value'})

# DELETE 請求
r = httpx.delete('https://httpbin.org/delete')

# HEAD 請求
r = httpx.head('https://httpbin.org/get')

# OPTIONS 請求
r = httpx.options('https://httpbin.org/get')

參數傳遞

若要以 GET 方式傳送參數資料,可以使用 params 來指定參數資料:

# 參數資料
params = {'key1': 'value1', 'key2': 'value2'}

# 以 GET 方式傳遞參數資料
r = httpx.get('https://httpbin.org/get', params=params)

# 檢視 HTTP 請求的 URL
print(r.url)
https://httpbin.org/get?key1=value1&key2=value2

我們也可以採用列表(list)的寫法來指定參數資料:

# 參數資料
params = {'key1': 'value1', 'key2': ['value2', 'value3']}

# 以 GET 方式傳遞參數資料
r = httpx.get('https://httpbin.org/get', params=params)

# 檢視 HTTP 請求的 URL
print(r.url)
https://httpbin.org/get?key1=value1&key2=value2&key2=value3

HTTP 回應資料編碼

HTTPX 會自動採用適合的編碼來處理接收到的資料:

import httpx

r = httpx.get('https://tw.yahoo.com/')

# 取得 HTML 內容
htmlContent = r.text

# 取得編碼
print(r.encoding)
UTF-8

我們也可以自行指定編碼,讓 HTTPX 以自訂的編碼來解析接收到的文字資料:

# 自行指定編碼
r.encoding = 'Big5'

# 取得 HTML 內容
htmlContent = r.text

二進位資料處理

回應資料的二進位內容可以透過 content 屬性來取得:

import httpx

r = httpx.get('https://httpbin.org/get')

# 取得二進位內容
binContent = r.content

HTTPX 會自動解壓縮任何以 gzip 或 deflate 壓縮的資料,另外如果系統有安裝 brotlipy 模組,也會自動解壓縮 brotli 壓縮的資料。

若要下載圖片,可以搭配其他圖片相關的模組來處理:

import httpx
from PIL import Image
from io import BytesIO

# 下載圖片
r = httpx.get('https://www.example.com/image.jpg')

# 讀取圖片資料
img = Image.open(BytesIO(r.content))

傳送檔案

若要上傳檔案,可以使用 files 指定要上傳的檔案清單:

import httpx

# 要上傳的檔案
files = {'upload-file': open('report.xls', 'rb')}

# 上傳檔案
r = httpx.post("https://httpbin.org/post", files=files)

傳送 JSON 格式資料

對於結構比較複雜的資料,可以使用 JSON 格式的方式來傳送:

import httpx

# 要上傳的結構化資料
data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}

# 以 JSON 格式上傳結構化資料
r = httpx.post("https://httpbin.org/post", json=data)

串流下載

當下載大量資料時,可以考慮使用串流的方式來處理資料,避免所有資料一次放進記憶體中,佔用太多記憶體資源:

import httpx

# 二進位串流處理
with httpx.stream("GET", "https://www.example.com") as r:
    for data in r.iter_bytes():
        print(data)

# 文字串流處理
with httpx.stream("GET", "https://www.example.com") as r:
    for text in r.iter_text():
        print(text)

# 逐行文字串流處理
with httpx.stream("GET", "https://www.example.com") as r:
    for line in r.iter_lines():
        print(line)

若要對原始資料(未解壓縮)進行串流處理,可以參考以下方式:

# 原始資料(未解壓縮)串流處理
with httpx.stream("GET", "https://www.example.com") as r:
    for chunk in r.iter_raw():
        print(chunk)

命令列 httpx 指令工具

除了標準的 Python 3 模組之外,HTTPX 同時也提供了命令列的指令工具,讓使用者直接使用簡單的指令即可建立 HTTP 請求。若需要 HTTPX 的指令工具,可以使用以下指令安裝:

# 安裝 HTTPX 模組(包含命令列指令)
pip install httpx[cli]

以下是一些常用的 httpx 指令範例。

傳送基本的 GET 請求:

# 傳送基本 GET 請求
httpx https://httpbin.org/get

若要在 GET 請求中附帶參數,可以使用 -p--params 只定參數的名稱與值:

# 在 GET 請求中附帶參數
httpx -p var1 value1 -p var2 value2 https://httpbin.org/get

若要以 POST 送出表單資料,可以使用 -m--method 指定採用 POST 方式,並以 -d--data 指定資料參數的名稱與值:

# 以 POST 送出表單資料
httpx -m POST -d var1 value1 -d var2 value2 https://httpbin.org/post

若要傳送檔案,可以用 -f--files 參數指定檔案名稱與檔案路徑:

# 以 POST 送出檔案
httpx -m POST -f my_name.jpg /path/my_file.jpg https://httpbin.org/post

若要設定 cookies,可以使用 --cookies 參數指定 cookies 的名稱與值:

# 設定 cookies
httpx --cookies var1 value1 --cookies var2 value2 https://httpbin.org/get

若要發送 JSON 格式的資料,可以使用 -j--json 餐數指定 JSON 格式的字串資料:

# 以 POST 傳送 JSON 資料
httpx -m POST -j '{"A":1}' https://httpbin.org/post

其餘更多 httpx 的參數用法可以使用 --help 參數查詢:

# 查詢 httpx 指令與參數用法
httpx --help
Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago