http.client 教程-如何使用 Python 标准库发送 HTTP 请求

发布于:2025-07-30 ⋅ 阅读:(19) ⋅ 点赞:(0)

http.client 教程-如何使用 Python 标准库发送 HTTP 请求

以下是 http.client 模块的详细使用教程,帮助你理解如何使用 Python 标准库发送 HTTP 请求:

1. http.client 概述

http.client 是 Python 内置的 HTTP 客户端库,提供了底层的 HTTP 协议实现,支持:

  • 发送 HTTP/1.1 请求
  • 处理响应状态码、头信息和内容
  • 支持 HTTPS(通过 HTTPSConnection
  • 支持基本认证、Cookie 等功能

优点无需额外安装依赖,适合轻量级 HTTP 交互

缺点:API 较为底层,使用复杂度高于 requests 库。

2. 基本使用流程

步骤 1:导入模块并创建连接

import http.client

# HTTP 连接

conn = http.client.HTTPConnection("example.com")

# HTTPS 连接(默认端口 443)

conn = http.client.HTTPSConnection("api.example.com")

# 指定端口(如 8080)

conn = http.client.HTTPConnection("localhost", 8080)

步骤 2:发送请求

# 发送 GET 请求

conn.request("GET", "/path/to/resource")

# 发送带参数的 GET 请求

conn.request("GET", "/search?q=python&page=1")

# 发送 POST 请求(带 JSON 数据)

headers = {"Content-Type": "application/json"}

body = '{"name": "test", "age": 30}'

conn.request("POST", "/users", body, headers)

步骤 3:获取响应

response = conn.getresponse()

# 获取响应状态码

status_code = response.status  # 如 200, 404, 500

# 获取响应头

headers = response.getheaders()

# 获取响应内容

data = response.read()  # 返回 bytes 类型

text = data.decode("utf-8")  # 转为字符串

步骤 4:关闭连接

conn.close()

3. 处理不同类型的请求

GET 请求示例

import http.client

conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")

conn.request("GET", "/posts/1")

response = conn.getresponse()

print(f"状态码: {response.status}")

print(f"响应头: {response.getheaders()}")

print(f"响应内容: {response.read().decode()}")

conn.close()

POST 请求示例(JSON 数据)

import http.client

import json

conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")

headers = {"Content-Type": "application/json"}

body = json.dumps({"title": "foo", "body": "bar", "userId": 1})

conn.request("POST", "/posts", body, headers)

response = conn.getresponse()

print(response.read().decode())

conn.close()

带参数的 POST 请求(表单数据)

import http.client

from urllib.parse import urlencode

conn = http.client.HTTPConnection("example.com")

headers = {"Content-Type": "application/x-www-form-urlencoded"}

params = urlencode({"username": "test", "password": "123456"})

conn.request("POST", "/login", params, headers)

response = conn.getresponse()

print(response.read().decode())

conn.close()

4. 处理响应

响应状态码

if response.status == 200:

    print("请求成功")

elif response.status == 404:

    print("资源不存在")

else:

    print(f"错误: {response.status}")

响应头处理

# 获取特定头信息

content_type = response.getheader("Content-Type")

print(f"内容类型: {content_type}")

# 获取所有头信息

headers = response.getheaders()

for header, value in headers:

    print(f"{header}: {value}")

响应内容处理

# 读取二进制内容

data = response.read()

# 根据 Content-Type 解码

content_type = response.getheader("Content-Type")

if "json" in content_type:

    import json

    json_data = json.loads(data)

elif "text" in content_type:

    text = data.decode("utf-8")

else:

    # 二进制数据(如图像、文件)

    with open("file.bin", "wb") as f:

        f.write(data)

5. 高级用法

设置超时时间

conn = http.client.HTTPSConnection("example.com", timeout=5)  # 5秒超时

处理重定向(301/302)

max_redirects = 3

current_url = "/initial-path"

redirect_count = 0

while redirect_count < max_redirects:

    conn.request("GET", current_url)

    response = conn.getresponse()

    

    if response.status in (301, 302):

        location = response.getheader("Location")

        current_url = location

        redirect_count += 1

    else:

        break  # 非重定向状态码,退出循环

设置请求头(如 User-Agent)

headers = {

    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",

    "Accept": "application/json"

}

conn.request("GET", "/api/data", headers=headers)

基本认证

import base64

username = "admin"

password = "secret"

auth_string = f"{username}:{password}"

auth_bytes = base64.b64encode(auth_string.encode())

auth_header = f"Basic {auth_bytes.decode()}"

headers = {"Authorization": auth_header}

conn.request("GET", "/protected", headers=headers)

6. 异常处理

import http.client

try:

    conn = http.client.HTTPSConnection("nonexistent-domain.com")

    conn.request("GET", "/")

    response = conn.getresponse()

except ConnectionRefusedError:

    print("连接被拒绝")

except TimeoutError:

    print("连接超时")

except http.client.InvalidURL:

    print("无效的 URL")

except Exception as e:

    print(f"发生错误: {e}")

finally:

    if conn:

        conn.close()

7. 完整示例:获取天气 API 数据

import http.client

import json

try:

    # 连接到天气API

    conn = http.client.HTTPSConnection("api.openweathermap.org")

    # API参数(城市ID和API密钥)

    city_id = "1850147"  # 东京的城市ID

    api_key = "YOUR_API_KEY"  # 替换为你的API密钥

    # 发送请求

    conn.request("GET", f"/data/2.5/weather?id={city_id}&appid={api_key}")

    # 获取响应

    response = conn.getresponse()

    if response.status == 200:

        data = json.loads(response.read().decode())

        print(f"城市: {data['name']}")

        print(f"天气: {data['weather'][0]['description']}")

        print(f"温度: {data['main']['temp'] - 273.15:.1f}°C")  # 转为摄氏度

    else:

        print(f"错误: {response.status} - {response.read().decode()}")

except Exception as e:

    print(f"发生异常: {e}")

finally:

    conn.close()

8. 与 requests 库对比

特性

http.client

requests

所属库

Python 标准库(无需安装)

第三方库(需 pip install

API 复杂度

底层,需要手动处理很多细节

高层,简洁易用

请求方法

request() 结合方法参数

get(), post(), put() 等

响应处理

手动解析状态码、头和内容

自动解析,提供 json() 方法

会话管理

需手动管理连接

自动管理会话(如 Cookie)

重定向处理

需手动实现

自动处理(可配置)

文件上传

复杂

简单(files 参数)

9. 常见问题解答

  • Q1:如何设置请求超时?

A:在创建连接时指定 timeout 参数,如 HTTPSConnection("example.com", timeout=10)

  • Q2:如何处理 HTTPS 证书验证?

A:默认验证证书。若需忽略,使用 context 参数:

import ssl

context = ssl._create_unverified_context()

conn = http.client.HTTPSConnection("example.com", context=context)

  • Q3:如何发送大文件?

A:使用分块传输(Chunked Transfer),需设置 Transfer-Encoding: chunked 头,手动分块发送。

通过这个教程,你应该能够掌握 http.client 的基本使用方法。在实际项目中,若追求更高的开发效率,推荐使用 requests 库;若需要底层控制或环境受限(如无第三方库),则 http.client 是更好的选择。


网站公告

今日签到

点亮在社区的每一天
去签到