Python

Python-网络高级编程

2024-09-11  本文已影响0人  阿凡提说AI

urllib3是一个用于编写HTTP客户端的Python库.
使用urllib3中的API向服务端发送HTTP请求,首先需要引入urllib3模块,然后创建PoolManager类的实例,该类用于管理连接池。最后通过request方法发送GET请求,request方法的返回值就是服务端的响应结果,通过data属性直接可以获得服务端的响应数据。
当向服务端发送HTTP GET请求时,而且请求字段值包含中文、空格等字符,需要对其进行编码。在urlllib.parse模块中有一个urlencode函数,可以将一个字典形式的请求值对作为参数传入urlencode函数,也可以使用fields关键字参数指定GET的请求字段。

使用urllib3模块发送HTTP请求是一个比较简单的过程。以下是如何使用urllib3发送一个包含中文和空格字符的GET请求的示例:
首先,确保您已经安装了urllib3模块。由于您要求不使用pip安装包,这里假设urllib3已经安装好了。
下面是发送HTTP GET请求的示例代码:

import urllib3
from urllib.parse import urlencode
# 创建PoolManager实例来管理连接池
http = urllib3.PoolManager()
# 定义要发送的GET请求参数
params = {
    'name': '张三',  # 包含中文
    'city': '北京 大兴',  # 包含空格
}
# 使用urlencode对参数进行编码
encoded_params = urlencode(params)
# 构造完整的URL
url = 'http://example.com/api?' + encoded_params
# 发送GET请求
response = http.request('GET', url)
# 输出响应结果
print(response.status)
print(response.data.decode('utf-8'))

在这段代码中:

使用Flask框架编写一个处理HTTP POST请求的服务端程序

from flask import Flask, request

app = Flask(__name__)

@app.route('/register', methods=['POST'])
def register():
    # 打印表单中提交的name和age字段
    print(request.form.get('name'))
    print(request.form.get('age'))
    return "注册成功"

if __name__ == '__main__':
    app.run()

在这个例子中,我们定义了一个名为/register的路由,它只接受POST方法。当客户端向这个路由发送POST请求时,register函数会被调用。我们使用request.form.get()方法来获取表单数据中名为’name’和’age’的字段值,并打印它们。

通过PoolManager对象中的request方法的headers关键字参数可以指定字典形式的HTTP请求头。
urllib3 是一个强大的、线程安全的 HTTP 客户端,它提供了许多高级功能,比如连接池管理、线程安全、客户端侧 SSL/TLS 验证等。
urllib3 中,PoolManager 是用于管理连接池的类,它提供了 request 方法,该方法可以用来发起 HTTP 请求。您确实可以通过 headers 关键字参数来指定 HTTP 请求头。以下是如何使用 PoolManager 的一个例子:

from urllib3 import PoolManager
http = PoolManager()
# 定义请求头
headers = {
    "User-Agent": "My User Agent 1.0",
    "Accept": "application/json",
}
# 发起一个GET请求,并指定请求头
response = http.request(
    'GET',
    'http://httpbin.org/get',
    headers=headers
)
# 打印响应内容
print(response.data.decode('utf-8'))

在这个例子中,我们首先创建了一个 PoolManager 实例。然后,我们定义了一个字典 headers,其中包含了我们想要发送的 HTTP 请求头。最后,我们使用 request 方法发起了一个 GET 请求,将 headers 字典作为 headers 参数传递。
请注意,urllib3requests 库中的一个依赖,通常情况下,直接使用 requests 库可以更方便地处理 HTTP 请求,因为它提供了一个更高级的 API。以下是如何使用 requests 库来设置请求头的例子:

import requests
# 定义请求头
headers = {
    "User-Agent": "My User Agent 1.0",
    "Accept": "application/json",
}
# 发起一个GET请求,并指定请求头
response = requests.get('http://httpbin.org/get', headers=headers)
# 打印响应内容
print(response.text)

在这个例子中,我们使用了 requests.get 方法,并直接在调用时传递了 headers 参数。这是在 Python 中处理 HTTP 请求的常见做法。

urllib3 库中,当你使用 PoolManager 对象的 request 方法发起一个 HTTP 请求时,它会返回一个 HTTPResponse 对象。这个对象包含了服务器的响应,你可以通过调用它的 info 方法来获取响应头信息。
以下是如何使用 HTTPResponse.info 方法来获取响应头的示例:

from urllib3 import PoolManager
# 创建 PoolManager 实例
http = PoolManager()
# 发起 HTTP 请求
response = http.request('GET', 'http://httpbin.org/get')
# 获取响应头信息
response_headers = response.info()
# 打印响应头信息
print(response_headers)

在这个例子中,response.info() 方法返回的是一个类似字典的对象,它包含了所有的响应头字段和值。你可以像访问字典一样访问这些响应头信息,例如:

# 打印特定的响应头字段
print('Server:', response_headers['Server'])
print('Content-Type:', response_headers['Content-Type'])

记得在使用完 HTTPResponse 对象后,如果需要的话,可以调用它的 close 方法来关闭底层的连接,释放资源。这在某些情况下是必要的,尤其是当你处理大量请求并且想要显式地管理连接池中的连接时。

在发送HTTP请求上传文件时,您可以使用urllib3库的PoolManager来构造一个multipart/form-data类型的请求。以下是如何使用urllib3request方法来上传文件的示例:

from urllib3 import PoolManager
# 创建 PoolManager 实例
http = PoolManager()
# 文件名和文件数据
file_name = 'example.jpg'
file_data = open(file_name, 'rb').read()  # 读取文件内容
file_type = 'image/jpeg'
# 构造表单字段
fields = {
    'file': (file_name, file_data, file_type)
}
# 目标URL
url = 'http://httpbin.org/post'
# 发送请求,上传文件
response = http.request('POST', url, fields=fields)
# 打印响应
print(response.status)
print(response.data.decode('utf-8'))
# 关闭文件
file_data.close()

在这个例子中,fields 字典的键 'file' 对应一个元组,其中包含三个元素:

  1. file_name: 文件名。
  2. file_data: 文件内容,需要以二进制读取模式打开文件。
  3. file_type: 文件的MIME类型。
    urllib3 会自动处理 multipart/form-data 编码,将文件作为表单的一部分发送到服务器。服务器端通常会解析这种类型的请求,并将上传的文件存储在服务器上。
    请注意,在处理文件时,应当确保在读取文件后正确地关闭文件,以避免资源泄露。在上面的代码中,使用 with 语句可以更安全地处理文件:
with open(file_name, 'rb') as file:
    file_data = file.read()
    # 现在可以使用 file_data 来发送请求
    # ...
# with 语句会自动关闭文件

Socket超时分为连接超时和读超时,连接超时是指在连接的过程中由于服务端的问题或域名(IP地址)弄错了而导致的无法连接服务器的情况。读超时是指从服务器读取数据时由于服务器的问题,导致长时间无法读取数据而产生的异常。

在Socket编程中,设置超时是非常重要的,它可以防止程序在等待网络操作完成时无限期地挂起。在Python的socket模块中,您可以通过以下方式设置超时:

import socket
# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置总超时时间为 5 秒
s.settimeout(5)
# 尝试连接到服务器
try:
    s.connect(('example.com', 80))  # 假设连接到 HTTP 服务的 80 端口
except socket.timeout:
    print("连接超时")
# 如果需要分别设置连接超时和读超时,可以使用如下方式:
# 注意:以下代码仅作为示例,实际上 Python socket 模块不支持这种设置方式
# timeout = Timeout(connect=2, read=3)
# s.settimeout(timeout.connect)  # 设置连接超时时间为 2 秒
# s.settimeout(timeout.read)     # 设置读超时时间为 3 秒
# 注意:实际上 Python socket 模块不支持这种分别设置连接超时和读超时的方法。
# 如果需要分别设置,可能需要使用更底层的库,如 select 或更高级的网络库,如 requests。
# 发送数据(省略)
# ...
# 尝试从服务器接收数据
try:
    data = s.recv(1024)
except socket.timeout:
    print("读超时")
# 关闭 socket
s.close()

请注意,Python的socket模块不支持直接设置独立的连接超时和读超时。在上面的代码中,Timeout(connect=2, read=3) 这一行只是一个示例,并不是有效的Python代码。如果您需要这样的功能,您可能需要使用selectors模块或asyncio库来实现更复杂的超时管理。

上一篇下一篇

猜你喜欢

热点阅读