Python urllib3
最后修改于 2024 年 1 月 29 日
Python urllib3 教程介绍了 Python urllib3 模块。我们将展示如何获取数据、发布数据、流式传输数据、使用 JSON 以及使用重定向。
超文本传输协议 (HTTP) 是一种用于分布式、协作式、超媒体信息系统的应用协议。HTTP 是万维网数据通信的基础。
Python urllib3
urllib3
模块是一个功能强大且易于使用的 Python HTTP 客户端。它支持线程安全、连接池、客户端 SSL/TLS 验证、带有多部分编码的文件上传、用于重试请求和处理 HTTP 重定向的助手、gzip 和 deflate 编码以及 HTTP 和 SOCKS 代理。
$ pip install urllib3
我们使用 pip
安装 urllib3
模块。
Python urllib3 版本
第一个程序打印 urllib3 模块的版本。
#!/usr/bin/python import urllib3 print(urllib3.__version__)
该程序打印 urllib3
的版本。
$ ./version.py 1.24.1
这是该示例的示例输出。
Python urllib3 状态
HTTP 响应状态代码指示特定的 HTTP 请求是否已成功完成。响应分为五个类
- 信息性响应(100–199)
- 成功响应(200–299)
- 重定向(300–399)
- 客户端错误(400–499)
- 服务器错误(500–599)
#!/usr/bin/python import urllib3 http = urllib3.PoolManager() url = 'http://webcode.me' resp = http.request('GET', url) print(resp.status)
该示例创建对 webcode.me
的 GET 请求。它打印响应的状态代码。
http = urllib3.PoolManager()
我们创建一个 PoolManager
来生成请求。它处理连接池和线程安全的所有细节。
url = 'http://webcode.me'
这是我们发送请求的 URL。
resp = http.request('GET', url)
使用 request
方法,我们对指定的 URL 发出 GET 请求。
print(resp.status)
我们打印响应的状态代码。
$ status.py 200
200 状态代码表示请求已成功。
Python urllib3 GET 请求
HTTP GET 方法请求指定资源的表示形式。
#!/usr/bin/python import urllib3 http = urllib3.PoolManager() url = 'http://webcode.me' resp = http.request('GET', url) print(resp.data.decode('utf-8'))
该示例向 webcode.me
网页发送 GET 请求。它返回主页的 HTML 代码。
req = http.request('GET', url)
生成 GET 请求。
print(resp.data.decode('utf-8'))
我们获取数据或响应,并将其解码为文本。
$ ./get_request.py <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body>
Python urllib3 HEAD 请求
HEAD 请求是没有消息主体的 GET 请求。
#!/usr/bin/python import urllib3 http = urllib3.PoolManager() url = 'http://webcode.me' resp = http.request('HEAD', url) print(resp.headers['Server']) print(resp.headers['Date']) print(resp.headers['Content-Type']) print(resp.headers['Last-Modified'])
在该示例中,我们创建对 webcode.me
网站的 HEAD 请求。
print(resp.headers['Server']) print(resp.headers['Date']) print(resp.headers['Content-Type']) print(resp.headers['Last-Modified'])
响应对象包含 headers
字典,其中包含各种标头字段,例如 server 和 date。
$ ./head_request.py nginx/1.6.2 Thu, 20 Feb 2020 14:35:14 GMT text/html Sat, 20 Jul 2019 11:49:25 GMT
从输出中我们可以看到该网站的 Web 服务器是 nginx,内容类型是 HTML 代码。
Python urllib3 HTTPS 请求
urllib3
提供客户端 TLS/SSL 验证。为此,我们需要下载 certifi
模块。 它是一个精心策划的根证书集合,用于在验证 TLS 主机的身份时验证 SSL 证书的可信度。 它已从 Requests 项目中提取。
$ pip install certifi
我们安装 certifi
。
import certifi print(certifi.where())
要引用已安装的证书颁发机构 (CA) 包,我们使用内置的 where
函数。
#!/usr/bin/python import urllib3 import certifi url = 'https://httpbin.org/anything' http = urllib3.PoolManager(ca_certs=certifi.where()) resp = http.request('GET', url) print(resp.status)
我们创建对 https://httpbin.org/anything
页面的 GET 请求。
http = urllib3.PoolManager(ca_certs=certifi.where())
我们将根 CA 包传递给 PoolManager
。 如果没有此 CA 包,该请求将发出以下警告: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised.
。
Python urllib3 查询参数
查询参数是统一资源定位符 (URL) 的一部分,它为指定的参数分配值。这是将数据发送到目标服务器的一种方式。
http://example.com/api/users?name=John%20Doe&occupation=gardener
查询参数在 ? 字符之后指定。多个字段用 & 分隔。特殊字符,如空格,会被编码。在上面的字符串中,空格被编码为 %20
值。
#!/usr/bin/python import urllib3 import certifi http = urllib3.PoolManager(ca_certs=certifi.where()) payload = {'name': 'Peter', 'age': 23} url = 'https://httpbin.org/get' req = http.request('GET', url, fields=payload) print(req.data.decode('utf-8'))
在此示例中,我们使用一些查询参数向 https://httpbin.org/get
发送 GET 请求。 该链接只是将一些数据返回给客户端,包括查询参数。 该站点用于测试 HTTP 请求。
payload = {'name': 'Peter', 'age': 23}
这是要发送的有效负载。
req = http.request('GET', url, fields=payload)
查询参数使用 fields
选项指定。
$ ./query_params.py { "args": { "age": "23", "name": "Peter" }, "headers": { "Accept-Encoding": "identity", "Host": "httpbin.org", "X-Amzn-Trace-Id": "Root=1-5e4ea45f-c3c9c721c848f8f81a3129d8" }, "origin": "188.167.251.9", "url": "https://httpbin.org/get?name=Peter&age=23" }
httpbin.org
响应了一个 JSON 字符串,其中也包括我们的有效负载。
Python urllib3 POST 请求
HTTP POST 方法将数据发送到服务器。它通常用于上传文件或提交完成的 Web 表单。
#!/usr/bin/python import urllib3 import certifi http = urllib3.PoolManager(ca_certs=certifi.where()) url = 'https://httpbin.org/post' req = http.request('POST', url, fields={'name': 'John Doe'}) print(req.data.decode('utf-8'))
该示例发送 POST 请求。 数据使用 fields
选项指定。
$ ./post_request.py { "args": {}, "data": "", "files": {}, "form": { "name": "John Doe" }, ... "url": "https://httpbin.org/post" }
Python urllib3 发送 JSON
在诸如 POST 或 PUT 之类的请求中,客户端通过 Content-Type
标头告诉服务器实际发送的数据类型。
#!/usr/bin/python import urllib3 import certifi import json http = urllib3.PoolManager(ca_certs=certifi.where()) payload = {'name': 'John Doe'} encoded_data = json.dumps(payload).encode('utf-8') resp = http.request( 'POST', 'https://httpbin.org/post', body=encoded_data, headers={'Content-Type': 'application/json'}) data = json.loads(resp.data.decode('utf-8'))['json'] print(data)
该示例发送 JSON 数据。
payload = {'name': 'John Doe'} encoded_data = json.dumps(payload).encode('utf-8')
我们将 JSON 数据编码为二进制格式。
resp = http.request( 'POST', 'https://httpbin.org/post', body=encoded_data, headers={'Content-Type': 'application/json'})
我们在请求中指定 Content-Type
标头。
data = json.loads(resp.data.decode('utf-8'))['json'] print(data)
我们将返回的数据解码回文本并将其打印到控制台。
Python urllib3 二进制数据
在以下示例中,我们下载二进制数据。
#!/usr/bin/python import urllib3 http = urllib3.PoolManager() url = 'http://webcode.me/favicon.ico' req = http.request('GET', url) with open('favicon.ico', 'wb') as f: f.write(req.data)
该示例下载一个小图标。
with open('favicon.ico', 'wb') as f: f.write(req.data)
req.data
采用二进制格式,我们可以直接将其写入磁盘。
Python urllib3 流式传输数据
分块传输编码是自 HTTP 1.1 起可用的流式数据传输机制。 在分块传输编码中,数据流被划分为一系列不重叠的块。
这些块被发送和接收,彼此独立。 每个块前面都有其大小(以字节为单位)。
将 preload_content
设置为 False
意味着 urllib3 将流式传输响应内容。 stream
方法迭代响应内容的块。 在流式传输时,我们应该调用 release_conn
以将 http 连接释放回连接池,以便可以重复使用。
#!/usr/bin/python import urllib3 import certifi url = "https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf" local_filename = url.split('/')[-1] http = urllib3.PoolManager(ca_certs=certifi.where()) resp = http.request( 'GET', url, preload_content=False) with open(local_filename, 'wb') as f: for chunk in resp.stream(1024): f.write(chunk) resp.release_conn()
在此示例中,我们下载一个 PDF 文件。
resp = http.request( 'GET', url, preload_content=False)
使用 preload_content=False
,我们启用流式传输。
with open(local_filename, 'wb') as f: for chunk in resp.stream(1024): f.write(chunk)
我们迭代数据块并将它们保存到文件中。
resp.release_conn()
最后,我们释放连接。
Python urllib3 重定向
重定向会将用户和搜索引擎发送到与他们最初请求的 URL 不同的 URL。 要遵循重定向,我们将 redirect
选项设置为 True
。
#!/usr/bin/python import urllib3 import certifi http = urllib3.PoolManager(ca_certs=certifi.where()) url = 'https://httpbin.org/redirect-to?url=/' resp = http.request('GET', url, redirect=True) print(resp.status) print(resp.geturl()) print(resp.info())
该示例遵循重定向。
$ ./redirect.py 200 / HTTPHeaderDict({'Date': 'Fri, 21 Feb 2020 12:49:29 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '9593', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'})
Python urllib3 Flask 示例
在以下示例中,我们向一个小的 Flask Web 应用程序发送请求。 在 Python Flask 教程中了解有关 Flask Web 框架的更多信息。
$ pip install flask
我们需要安装 flask
模块。
#!/usr/bin/python from flask import Flask from flask import request app = Flask(__name__) @app.route('/headers') def hello(): ua = request.headers.get('user-agent') ka = request.headers.get('connection') return f'User agent: {ua}; Connection: {ka}'
该应用程序只有一个路由。 它将请求的用户代理和连接标头字段发送给客户端。
#!/usr/bin/python import urllib3 http = urllib3.PoolManager() url = 'localhost:5000/headers' headers = urllib3.make_headers(keep_alive=True, user_agent='Python program') resp = http.request('GET', url, headers=headers) print(resp.data.decode('utf-8'))
在此程序中,我们向 Flask 应用程序发送请求。
url = 'localhost:5000/headers'
默认情况下,Flask 在端口 5000 上运行。
headers = urllib3.make_headers(keep_alive=True, user_agent='Python program')
使用 make_headers
辅助方法,我们创建一个标头字典。
resp = http.request('GET', url, headers=headers)
我们向 URL 发送 GET 请求; 我们指定标头字典。
print(resp.data.decode('utf-8'))
我们将响应打印到终端。
$ export FLASK_APP=app.py $ flask run
我们运行 Flask 应用程序。
$ ./send_req.py User agent: Python program; Connection: keep-alive
从不同的终端,我们启动 send_req.py
程序。
来源
在本文中,我们使用了 Python urllib3 模块。
作者
列出所有 Python 教程。