【问题标题】:Python3 requests.get is too slowPython3 requests.get 太慢了
【发布时间】:2019-05-01 15:39:15
【问题描述】:

编辑添加信息:

请求版本:2.21.0

服务器信息:一个 Windows python 实现,包括 10 个 threading.Thread 实例,每个实例创建 HTTPServer 带有一个基于 BaseHTTPRequestHandler 的处理程序。我的 do_GET 看起来像这样:

def do_GET(self):
    rc = 'some response'
    self.send_response(200)
    self.send_header('Content-type', 'text/html')
    self.send_header('Access-Control-Allow-Origin', '*')
    self.end_headers()
    self.wfile.write(rc.encode('utf-8'))

我的行为很奇怪。

使用curl 命令行,GET 命令快速完成:

curl "http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=1"

但是,使用 python 的requests.get() 花费太多时间。我被隔离到了

python -c "import requests; requests.get('http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=1')"

我在这里浏览了许多其他问题并尝试了很多东西,但都没有成功。

以下是我的一些发现:

  • 如果我添加timeout=0.2,通话将很快结束,没有任何错误。
  • 但是,添加 timeout=5 或 timeout=(5,5)` 不会使其花费更长的时间。在返回结果之前,它似乎总是要等待 整整一秒
  • 使用会话包装器并取消保持活动状态并没有改善。我的意思是:
with requests.Session() as session:
    session.headers.update({'Connection': 'close'})
    url = "http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=%d&tmr=0" % i
    session.get(url, timeout=2)
  • 启用完全调试,我得到以下输出:
url=http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=0 DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:3020 发送:b'GET /pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=0 HTTP/1.1\r\n主机:localhost:3020\r\n用户代理:python-requests/2.21 .0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: close\r\n\r\n' 回复:'HTTP/1.0 200 OK\r\n' 标头:服务器:BaseHTTP/0.6 Python/3.7.2 标题:日期:格林威治标准时间 2019 年 5 月 1 日星期三 15:28:29 标题:内容类型:文本/html 标头:访问控制允许来源:* DEBUG:urllib3.connectionpool:http://localhost:3020 "GET /pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=0 HTTP/1.1" 200 无 url=http://localhost:3020/pbio/powermtr?cmd=read-power-density DEBUG:urllib3.connectionpool:重置断开的连接:localhost 在这里稍作停顿 send: b'GET /pbio/powermtr?cmd=read-power-density HTTP/1.1\r\nHost: localhost:3020\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip , 放气\r\n接受: */*\r\n连接: 关闭\r\n\r\n' 回复:'HTTP/1.0 200 OK\r\n' 标头:服务器:BaseHTTP/0.6 Python/3.7.2 标题:日期:格林威治标准时间 2019 年 5 月 1 日星期三 15:28:30 标题:内容类型:文本/html 标头:访问控制允许来源:* DEBUG:urllib3.connectionpool:http://localhost:3020 "GET /pbio/powermtr?cmd=read-power-density HTTP/1.1" 200 无 6.710,i=4 url=http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=4&tmr=0 DEBUG:urllib3.connectionpool:重置断开的连接:localhost 在这里稍作停顿 ...

【问题讨论】:

  • 请求版本
  • 这个连接到什么服务器?您有该设置的任何性能指标吗?如果您将http://localhost:3020/pbio/button2 替换为http://httpbin.org/get,您是否看到相同的性能差异?
  • 我可能在这里忽略了一些明显的事情,但是当你的 curl 显然只会发出一个请求时,你的 python 调试确实 two 获取请求。进一步排查,你也可以curl -v "http://localhost:3020/pbio/button2?cmd=uz-crosslink-leds&g1=0&g2=0&g3=0&g4=1&tmr=1"然后交叉检查curl的get请求和python匹配的get请求
  • 另一个注意点:curl 无法保持连接打开,因为它会为每个进程发出一个请求。因此,保持连接打开并在超时后将其丢弃的行为不端的服务器不会困扰curl,因为它已经在必要时关闭了连接。
  • 最后:Connection: close 是 HTTP/1.1 标头,但您要连接的服务器声明它实现了 HTTP/1.0。正确关闭套接字是服务器的责任,显然这里没有这样做。

标签: python-3.x python-requests


【解决方案1】:

来自docs

超时不是整个响应下载的时间限制;相反,如果服务器在 timeout 秒内没有发出响应(更准确地说,如果在 timeout 秒内底层套接字上没有收到任何字节),则会引发异常。 如果没有明确指定超时,请求不会超时。

【讨论】:

    猜你喜欢
    • 2013-03-10
    • 2014-06-07
    • 2016-05-31
    • 2011-07-07
    • 2015-08-23
    • 2012-07-05
    • 2016-01-08
    • 2014-03-12
    • 2021-03-26
    相关资源
    最近更新 更多