【问题标题】:Issue with sending POST requests using the library requests使用库请求发送 POST 请求的问题
【发布时间】:2015-07-07 16:00:54
【问题描述】:
import requests
while True: 
    try:
        posting = requests.post(url,json = data,headers,timeout = 3.05)
    except requests.exceptions.ConnectionError as e: 
        continue
    # If a read_timeout error occurs, start from the beginning of the loop
    except requests.exceptions.ReadTimeout as e:  
        continue

更多代码的链接:Multiple accidental POST requests in Python 此代码使用 requests 库无限期地执行 POST 请求。我注意到当尝试多次失败并且while循环多次启动时,当我最终可以发送发布请求时,我会在同一秒内从服务器端找到多个条目。我正在同时写入一个 txt 文件,它只显示一个条目。每个条目是 5 个读数。这是图书馆本身的问题吗?有没有办法来解决这个问题?!无论我提出什么样的条件,它仍然不起作用:/! You can notice the reading at 12:11:13 has 6 parameters per second while at 12:14:30 (after the delay, it should be every 10 seconds) it is a few entries at the same second!!! 3 entries that make up 18 readings in one second, instead of 6 only!

【问题讨论】:

  • 这里的预期功能是什么?
  • 该代码应该发送一个 GET 请求,然后 POST 并重复。有时由于网络问题,POST 请求失败了几次,所以我重复 2 次,如果已发布,否则 GET 并尝试再次发布。有时当尝试 POST 但失败时,经过几次尝试,它最终会 POST 但爆出一组条目而不是一个条目。如图所示。图为服务器端。
  • 我认为我们需要更多代码。另外,请修正你的缩进——它们在 Python 中很重要!最后,您能再看看.post 方法中的参数吗?他们很混乱。
  • 我认为while True: 之后的所有内容都应该缩进另一个级别。在 Python 中,您必须在关键字参数(如 json = datatimeout = 3.05)之前有所有非关键字参数(如 urlheaders)。但我实际上假设你的意思是.post(url, data=json, headers=headers, timeout=3.05)。无论如何,你的代码肯定不会像问题中写的那样运行。
  • 不,坚持json=data,我只是把它翻过来了。

标签: python python-requests try-except


【解决方案1】:

看起来服务器接收到您的请求并对其采取行动,但未能及时响应(3 秒是一个非常低的超时,负载峰值/分页操作很容易使服务器错过它,除非它采用特殊措施)。我建议

  • 异步处理请求(例如生成线程;Asynchronous Requests with Python requests 讨论了使用 requests 执行此操作的方法)并且不使用超时(TCP 有自己的超时,让它失败)。
  • reuse the connection(s)(TCP 有相当多的连接建立/断开开销)或改用 UDP。
  • 包括一些“提示”(ID、时间戳等)以防止服务器添加重复记录。 (我认为这是一种解决方法,因为真正的问题是您不确定您的请求是否已得到处理。)

从服务器端,您可能希望:

  • 尽快回复并稍后根据信息采取行动。不要让待处理的操作阻止对进一步请求的响应。

【讨论】:

  • 非常感谢您的详尽回答。我昨天使用了您关于删除超时的建议,令人惊讶的是我仍然遇到了同样的问题,但规模较小(一次只有两个条目)。但是,似乎这个问题仅在我的观察中出现 readtimeout 异常时才会出现。我仍将很快使用和测试异步请求,但我想通知您,看看您是否对此更新有任何意见。
  • 1) 通过消除timeout,您只会停止干扰 TCP 的交付工作(因此,自然会获得更好的交付)。没有什么可以确保您在 任何 时间范围内不响应服务器,只有您自己决定在最终放弃之前尝试多长时间。 1.1)如果您可以访问服务器,您可以从它的侧面诊断问题,以找出需要这么长时间的原因。 2)“一次两个条目”(而不是一个)可能是由于您没有使用异步 I/O 造成的:如果 I/O 花费的时间足够长,您的程序可能错过了下一次发送的时间并直接跳转到下一个。
  • 我研究了异步请求,现在我的意思是什么。我发现问题主要发生在出现读取超时错误时。在大多数情况下,它会发送 POST 请求,但服务器没有响应,所以我会再次发送它,而第一个已经发送。当服务器最终响应时,这会导致两个条目,或者更多,这取决于我在相同的有问题的超时期间重新发送请求的次数。使用keep-alive来重用,是不是意味着我需要为GET和POST都创建一个session来维护同一个连接?
  • 基本上 atm 我试图最小化多个条目,因为无论丢失的数据如何,我似乎都无法应对网络故障等。但是由于读取超时会导致这种情况,也许我可以做些什么?是不是使用 keep-alive/Session() 仍将允许同一连接中的多个条目?!或者有一种方法可以检查是否在没有读取超时的情况下建立了连接,然后我可以发送数据?!
猜你喜欢
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
相关资源
最近更新 更多