【问题标题】:Python-Requests close http connectionPython-请求关闭 http 连接
【发布时间】:2012-04-11 22:54:13
【问题描述】:

我想知道,你如何关闭与 Requests (python-requests.org) 的连接?

httplibHTTPConnection.close(),但我该如何处理 Requests?

代码:

r = requests.post("https://stream.twitter.com/1/statuses/filter.json", data={'track':toTrack}, auth=('username', 'passwd'))
for line in r.iter_lines():
    if line:
        self.mongo['db'].tweets.insert(json.loads(line))

【问题讨论】:

标签: python http urllib2 httplib python-requests


【解决方案1】:

我认为关闭连接的更可靠方法是明确告诉服务器以compliant with HTTP specification的方式关闭它:

HTTP/1.1 为发送者定义了“关闭”连接选项 表示连接将在完成后关闭 回复。例如,

   Connection: close

在请求或响应头字段中表明 连接不应该被认为是“持久的”(第 8.1 节) 当前请求/响应已完成。

Connection: close 标头被添加到实际请求中:

r = requests.post(url=url, data=body, headers={'Connection':'close'})

【讨论】:

  • 在这种情况下,什么是“身体”?随便{}?
  • @Brad 这取决于内容类型,例如如果你想发送application/json,你可以使用data=json.dumps(payload),如果你只是想发送一个普通的form-encoded payload,你可以使用data={"k1":"v1", .. .}。在此处查看更多详细信息:docs.python-requests.org/en/latest/user/quickstart/…
  • 正在使用 here 但由于某种原因,连接似乎并没有真正关闭 - 我注意到因为我的操作系统用完了端口 - 如果该连接正确关闭,恕我直言。 ://
【解决方案2】:

我来这个问题是为了解决"too many open files" error,但我在我的代码中使用requests.session()。几次搜索后,我在Python Requests Documentation 上找到了答案,它建议使用with 块,这样即使有未处理的异常,会话也会关闭:

with requests.Session() as s:
    s.get('http://google.com')

如果您不使用 Session,您实际上可以做同样的事情:https://2.python-requests.org/en/master/user/advanced/#session-objects

with requests.get('http://httpbin.org/get', stream=True) as r:
    # Do something

【讨论】:

  • 我应该否决其他 cmets 以帮助这个 cmet 上升?
  • @dmigo:不。只有在答案在某些方面错误或对所提出的问题无用时才投反对票。
  • 假设我在一个函数中使用“with”创建了一个会话并返回该会话。在我所有的测试中使用会话。我怎么知道会话是否终止?
  • @manojprashantk 我能给出的最佳答案是在您的代码中进行测试。一旦您离开 with 块,请求可能会被关闭,但您应该阅读上下文管理器,因为它可能对您的问题有更多答案:docs.python.org/2/reference/datamodel.html#context-managers
  • 你确定这行得通吗?幕后的 requests.get() 也使用相同的构造,并且 keep-alive 仍在工作......
【解决方案3】:

正如here 所讨论的那样,实际上并没有 HTTP 连接这样的东西,而 httplib 所指的 HTTPConnection 实际上是底层 TCP 连接,它根本不了解您的请求。请求将其抽象出来,您将永远看不到它。

最新版本的 Requests 实际上确实在您发出请求后保持 TCP 连接处于活动状态。如果您确实希望关闭 TCP 连接,您只需将请求配置为不使用 keep-alive

s = requests.session()
s.config['keep_alive'] = False

【讨论】:

  • 或者s = requests.session(config={'keep_alive': False})
  • OP 询问如何关闭流式响应。我看不出在会话中设置 keep-alive 对那里有什么帮助。围绕这个问题,requests 和 urllib3 最近有几张票:github.com/shazow/urllib3/pull/132github.com/kennethreitz/requests/issues/1073github.com/kennethreitz/requests/issues/1041
  • 当前的request 版本不支持关闭 Keep-Alive。
  • 从当前版本开始,您可以通过读取 Response.content(或调用 Response.content 的 Response.text)确保流连接返回到池中。但是,如果您在没有阅读它们的情况下囤积 Response 对象,您将不会释放您的连接:Documentation
  • TypeError: session() got an unexpected keyword argument 'config'
【解决方案4】:

请使用response.close()关闭以避免“打开文件过多”错误

例如:

r = requests.post("https://stream.twitter.com/1/statuses/filter.json", data={'track':toTrack}, auth=('username', 'passwd'))
....
r.close()

【讨论】:

  • 我正在寻找这个问题的答案!
  • 最大是多少。在给出错误“打开的文件太多”之前,会话可以处理的连接数
【解决方案5】:

在 Requests 1.X 上,连接在响应对象上可用:

r = requests.post("https://stream.twitter.com/1/statuses/filter.json",
                  data={'track': toTrack}, auth=('username', 'passwd'))

r.connection.close()

【讨论】:

    【解决方案6】:

    这对我有用:

    res = requests.get(<url>, timeout=10).content
    requests.session().close()
    

    【讨论】:

      【解决方案7】:

      为了删除请求中的“keep-alive”标头,我只是从 Request 对象中创建了它,然后使用 Session 发送它

      headers = {
      'Host' : '1.2.3.4',
      'User-Agent' : 'Test client (x86_64-pc-linux-gnu 7.16.3)',
      'Accept' : '*/*',
      'Accept-Encoding' : 'deflate, gzip',
      'Accept-Language' : 'it_IT'
      }
      
      url = "https://stream.twitter.com/1/statuses/filter.json"
      #r = requests.get(url, headers = headers) #this triggers keep-alive: True
      s = requests.Session()
      r = requests.Request('GET', url, headers)
      

      【讨论】:

        【解决方案8】:

        根据最新的请求(2.25.1),requests.&lt;method&gt;会默认关闭连接

        with sessions.Session() as session:
            return session.request(method=method, url=url, **kwargs)
        

        https://github.com/psf/requests/blob/master/requests/api.py#L60

        因此,如果您使用最新版本的请求,似乎我们不需要自己关闭连接。

        另外,如果您需要在同一个会话中发送多次请求,最好使用requests.Session() 而不是多次打开/关闭连接。 例如:

        with requests.Session() as s:
            r = s.get('https://example.org/1/')
            print(r.text)
            r = s.get('https://example.org/2/')
            print(r.text)
            r = s.get('https://example.org/3/')
            print(r.text)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-27
          • 2022-12-12
          • 2012-02-06
          • 2020-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-11
          相关资源
          最近更新 更多