解决 requests 库 URL 编码问题

457 阅读2分钟

在使用 requests 库进行 URL 请求时,经常会遇到需要对 URL 进行编码的情况。然而,在某些情况下,需要发送未编码的 URL,例如用于测试防火墙配置。但根据实际测试结果,即使按照 requests 库官方文档中的解决方法,发送的 URL 仍然会被编码。这个问题由用户 LudiusMaximus 在 bug #6115 中提出。

解决方案

为了解决这个问题,我们需要找到一种方法来防止 requests 库对 URL 进行编码。一种可能的解决方案是使用 requests 库提供的 prepare 方法来创建一个预处理的请求,然后使用此请求来发送请求。

以下是一个示例代码:

import requests

# 创建一个会话对象
s = requests.Session()

# 配置代理和关闭 SSL 验证(仅用于示例,生产环境中需要谨慎使用)
s.proxies = {
    "http": "http://127.0.0.1:8080",
    "https": "http://127.0.0.1:8080",
}
s.verify = False

# 定义基本 URL 和查询参数
base_url = 'https://www.example.com/search'
query = '?date_range=2017-01-01|2017-03-01'

# 创建一个请求对象
req = requests.Request('GET', base_url)

# 使用 prepare 方法创建预处理请求
p = req.prepare()

# 将查询参数添加到预处理请求的 URL 中
p.url += query

# 使用预处理请求发送请求
req = p
resp = s.send(req)

# 打印最终的请求 URL
print(resp.request.url)

在这段代码中,首先创建了一个 requests.Session 对象,配置了代理并关闭了 SSL 验证(仅用于示例,实际生产环境中需要小心使用)。然后,定义了基本的 URL 和查询参数,并创建了一个请求对象。接着,使用 prepare 方法创建了一个预处理请求,并将查询参数添加到预处理请求的 URL 中。最后,使用预处理请求来发送实际请求。这样,requests 库就不会对 URL 进行编码,解决了该问题。

通过这种方式,你可以在需要发送未编码的 URL 的情况下,使用 requests 库来进行请求,确保 URL 不被自动编码。但请注意,在生产环境中,关闭 SSL 验证和使用代理需要谨慎处理,以确保安全性和可靠性。

36927a97e2083b92f9b9b9fe379c784.png