【问题标题】:How to resolve Requests get not working over VPN?如何解决请求无法通过 VPN 工作?
【发布时间】:2018-10-09 16:54:06
【问题描述】:

我正在尝试使用 python 中的请求来抓取网站。

url = "https://stackoverflow.com/questions/23013220/max-retries-exceeded-with-url"
# set the headers like we are a browser,
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'}

# download the homepage
s = requests.Session()
s.trust_env = False
response = s.get(url, headers=headers )

当我使用我的个人 wifi 时,这一切正常。但是,当我连接到我公司的 VPN 时,我收到以下错误。

ConnectionError: HTTPSConnectionPool(host='stackoverflow.com', port=443): 最大重试次数超出了 url: /questions/23013220/max-retries-exceeded-with-url (由 NewConnectionError(': 无法建立新连接:[WinError 10061] 无法建立连接,因为目标机器主动拒绝它',))

现在,我需要它来通过我公司的 VPN 工作,因为我需要访问一个只能在该 VPN 上工作的网站。如何解决?

【问题讨论】:

    标签: python python-requests anaconda


    【解决方案1】:

    就我而言,问题与 IPv6 有关。

    我们的 VPN 使用了拆分隧道,而且 VPN 配置似乎不支持 IPv6。

    例如,这将永远挂起:

    requests.get('https://pokeapi.co/api/v2/pokemon')
    

    但是如果加了超时,请求成功:

    requests.get('https://pokeapi.co/api/v2/pokemon', timeout=1)
    

    但并非所有机器都有这个问题。所以我比较了两台不同机器的输出:

    import socket
    
    for line in socket.getaddrinfo('pokeapi.co', 443):
        print(line)
    

    工作的只返回 IPv4 地址。非工作机器返回 IPv4 和 IPv6 地址。

    因此,在指定超时后,我的理论是 python 在 IPv6 上快速失败,然后转移到 IPv4,请求成功。

    最终我们通过在机器上禁用 IPv6 解决了这个问题:

    networksetup -setv6off "Wi-Fi"
    

    但我认为这可以通过 VPN 配置解决。

    【讨论】:

      【解决方案2】:

      这样试试怎么样:

      url = "https://stackoverflow.com/questions/23013220/max-retries-exceeded-with-url"
      ua = UserAgent()
      headers = headers = {"User-Agent": ua.random}
      
      # download the homepage
      s = requests.Session()
      s.trust_env = False
      response = s.get(url, headers=headers)
      

      好像是UserAgent()设置不同造成的。

      【讨论】:

        【解决方案3】:

        尝试设置trust_env = None

        trust_env = 无# 代理配置、默认身份验证等的信任环境设置。

        或者您可以禁用特定域的代理。 The question

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

        【讨论】:

        • @user1690356 你能用你的代码访问其他网站(使用https)吗?
        • @user1690356 尝试设置你的headers {'Connection': 'close'} 或者设置 requests.adapters.DEFAULT_RETRIES = 5 ,其他原因会出现这个错误是频繁访问
        【解决方案4】:

        在我的组织中,我必须在 VPN 下针对不同的地理位置运行我的程序。所以我们有多个代理配置。

        我发现使用名为 PyPAC 的包自动获取我的代理详细信息更简单

        from pypac import PACSession
        from requests.auth import HTTPProxyAuth
        session = PACSession()
        # when the username and password is required
        # session = PACSession(proxy_auth=HTTPProxyAuth(name, password)) 
        
        r = session.get('http://example.org')
        

        这是如何工作的:

        包定位组织配置的 PAC 文件。此文件包含代理配置详细信息 (more info)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-13
          • 2014-06-12
          • 2013-12-01
          • 1970-01-01
          • 2019-08-23
          • 2019-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多