【问题标题】:requests: how to disable / bypass proxy请求:如何禁用/绕过代理
【发布时间】:2015-04-15 18:57:16
【问题描述】:

我得到一个网址:

r = requests.get("http://myserver.com")

正如我在“myserver.com”的“access.log”中看到的,使用了客户端的系统代理。但我想通过requests 完全禁用代理。

【问题讨论】:

  • 向请求中添加 proxies=None 是否有效?
  • @Lesleh 是 proxies 关键字参数的默认值,这意味着它根本不会改变行为。
  • @Lesleh 我试过了,不幸的是,它不起作用。 :(

标签: python python-requests


【解决方案1】:

我目前知道的完全禁用代理的唯一方法如下:

  • 创建会话
  • session.trust_env 设置为False
  • 使用该会话创建您的请求
import requests

session = requests.Session()
session.trust_env = False

response = session.get('http://www.stackoverflow.com')

这是基于this comment by Lukasarequests.Session.trust_env 的(有限)文档。

注意:trust_env 设置为False 也会忽略以下内容:

  • 来自.netrc (code) 的身份验证信息
  • REQUESTS_CA_BUNDLECURL_CA_BUNDLE (code) 中定义的CA 包

但是,如果您只想禁用特定域的代理(例如 localhost),您可以使用 NO_PROXY environment variable

import os
import requests

os.environ['NO_PROXY'] = 'stackoverflow.com'

response = requests.get('http://www.stackoverflow.com')

【讨论】:

  • 除了禁用代理之外,trust_env=False 还有其他(副作用)吗?
  • 实际上,在我的一台服务器上,no_proxy 是正确答案(小写)。
  • 另一个技巧是让 urllib.getproxies 返回一个非空字典 (urllib.getproxies=lambda: {'z':'z'})。那么请求将不会从 env 和 os 设置中获取代理设置。
  • os.environ['NO_PROXY'] = os.environ['NO_PROXY'] + '\,'+ 'stackoverflow.com' 为了不替换您的默认代理,附加到列表将做
  • trust_env = False 解决方案完美运行,感谢您的解决方案!
【解决方案2】:

请求库尊重环境变量。 http://docs.python-requests.org/en/latest/user/advanced/#proxies

所以尝试删除环境变量 HTTP_PROXY 和 HTTPS_PROXY。

import os
for k in list(os.environ.keys()):
    if k.lower().endswith('_proxy'):
        del os.environ[k]

【讨论】:

  • 它绝对不会检查Mac上的环境变量。
【解决方案3】:

您可以为每个请求选择代理。来自the docs

import requests

proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "http://10.10.1.10:1080",
}

requests.get("http://example.org", proxies=proxies)

所以要禁用代理,只需将每个设置为无:

import requests

proxies = {
  "http": None,
  "https": None,
}

requests.get("http://example.org", proxies=proxies)

【讨论】:

  • 您是否检查过第二种情况。就我而言,它不起作用,即它仍在使用系统代理。
  • @sonukumar “第二种情况”是什么意思?
  • 哦!我的意思是使用代理参数来获取方法。
  • @sonukumar 我再次对其进行了测试,并验证它至少适用于我的系统和网络。检查我链接到的文档,看看是否还有我没有提到的其他内容。当然,如果您可以验证它在您的系统上不起作用,您可以随时提出另一个问题。
  • 如果你只是使用 HTTP 那么你不需要设置"https": None,对于那些想知道的人
【解决方案4】:

阻止 requests/urllib 代理任何请求的方法是将no_proxy(或NO_PROXY)环境变量设置为*,例如在 bash 中:

export no_proxy='*'

或者来自 Python:

import os
os.environ['no_proxy'] = '*' 

要理解为什么会这样是因为urllib.request.getproxies 函数首先检查环境变量中设置的任何代理(例如 http_proxy 等),或者如果没有设置,那么它将使用特定于平台的调用检查系统配置的代理(例如 On MacOS 将使用系统 scutil/configd 接口进行检查,在 Windows 上将检查注册表)。

然后,当 urllib 尝试使用任何代理时,proxyHandler 函数它将检查 no_proxy 环境变量的存在和设置 - 可以设置为如上所述的特定主机名,也可以设置特殊的* 所有主机绕过代理的值。

【讨论】:

  • 使用* 对我不起作用。但是,我只有少数例外,因此明确列出它们效果很好:export no_proxy='site1.com, site2.domain.com, site3.gov.com'
【解决方案5】:

使用 Python3 jtpereyda 的 solution 不起作用,但以下操作:

proxies = {
    "http": "",
    "https": "",
}

【讨论】:

    【解决方案6】:

    r = requests.post('https://localhost:44336/api/',data='',verify=False)

    您好,我在连接 localhost 以访问我的 .net 后端时遇到了同样的问题 来自带有请求模块的 python 脚本。 这对我有用。 我将 verify 设置为 False 取消默认 SSL 验证。

    P.s - 上面的代码会抛出一个可以被下面忽略的警告

    导入 urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    r=requests.post('https://localhost:44336/api/',data='',verify=False)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-08
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多