美文网首页Python
Python-网络高级编程

Python-网络高级编程

作者: 阿凡提说AI | 来源:发表于2024-09-11 00:15 被阅读0次

    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'))
    

    在这段代码中:

    • urlencode 函数用于将字典形式的请求参数编码成URL编码的字符串。
    • http.request('GET', url) 用于发送GET请求,其中url是包含查询参数的完整URL。
    • response.status 是响应的状态码。
    • response.data.decode('utf-8') 是将响应体数据解码成字符串,这里假设服务端返回的数据是UTF-8编码的。
      请注意,当处理HTTP响应时,应该检查响应的状态码和异常。此外,如果服务端期望接收JSON或其他格式的数据,可能需要对发送的数据进行相应的序列化处理。

    使用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模块中,您可以通过以下方式设置超时:

    • timeout 参数:设置一个总超时时间,这个时间适用于连接操作和接收数据操作。
    • settimeout() 方法:为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库来实现更复杂的超时管理。

    相关文章

      网友评论

        本文标题:Python-网络高级编程

        本文链接:https://www.haomeiwen.com/subject/bdysljtx.html