【问题标题】:Multiple accidental POST requests in PythonPython中的多个意外POST请求
【发布时间】:2015-07-03 07:30:06
【问题描述】:

我有这个程序使用请求库发送 GET 请求,然后将 POST 请求发送到另一台服务器。

import requests 

# inside the loop : 
headers = {'charset':'utf-8','Content-Type':'application/json'}
url = "http://someurl/_get_v2.php"
data = jenal

try :
    resp = requests.post(url,json=data,headers=headers, timeout=(connect_timeout,read_timeout))

    print "Post request sent" 
# If a connection error occurs, start from the beginning of the loop
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
time.sleep(10)

这是主循环的 POST 部分。我使用了 try ,除非程序遇到延迟,我不希望它因任何错误而停止,而是刷新并从循环的开头继续,以此类推。从逻辑上讲,程序应该没问题,但是当突然出现多个延迟时,程序会同时发送多个 POST 请求。

例如:日志应该是这样的: 10 发送。 20 发送。 30 发送。 已发送 45 个(延迟 5 秒)。 55已发送

但是发生的事情是这样的: 已发送 10 个 已发送 20 个 已发送 30 个 延迟..
45 已发送 45 已发送 已发送 45 个(同时发送了几份数据,这损坏了我的数据库) 55已发送

我应该如何防止多余的副本?

这是程序的第一部分。如果帖子部分有任何内容,这部分会重复,我每次都能看到打印:

connect_timeout = 3.05
read_timeout = 2

while True:
loop_time_start = time.time()
# GET

url_source = 'http://something/api_json.asp?cmd=list_metering&auth=YWRtaW46YWRtaW4='
try: 
    url = requests.get(url_source)
    print "GET request sent" 
except requests.exceptions.ConnectionError as e: continue

【问题讨论】:

  • 如果你给它添加一个boolean,在POST的时候,把它设置为True..posting = True,当你发现一个错误或者完成POST,把它设置为False ..posting = False.那么你可以说if not posting:。
  • @RussellHickey 先生,我要把它放在 POST 请求中吗?!
  • 把它放在try:、if not posting: try: posting = True之外。然后在您的print 和excepts 中放入posting = False...

标签: python python-requests


【解决方案1】:

如果在代码中添加计时器会怎样。

import requests 
from datetime import datetime, time

posting = False

# inside the loop :

if not posting:
    posting = True

    headers = {'charset':'utf-8','Content-Type':'application/json'}
    url = "http://someurl/_get_v2.php"
    data = jenal

    start = datetime.now()
    try :
        resp = requests.post(url,json=data,headers=headers,timeout=(connect_timeout,read_timeout))

        print "Post request sent" 

        posting = False

    except requests.exceptions.ConnectionError as e:
        # If you continue here, then there will be no sleep.
        # If your POST fails straight away, it tries again straight away. 

        # You should print/log here so you know which exception is being caught.

        # Add Timer
        end = datetime.combine(start.date(), time(0))

        ShouldISleep(start, end)

        posting = False

        continue

    except requests.exceptions.ReadTimeout as e:
        # If you continue here, then there will be no sleep.
        # If your POST fails straight away, it tries again straight away.

        # You should print/log here so you know which exception is being caught.

        # Add Timer
        end = datetime.combine(start.date(), time(0))

        ShouldISleep(start, end)

        posting = False

        continue

    time.sleep(10)

创建一个函数

def ShouldISleep(t1, t2):
    passed = (t1 - t2).seconds
    if passed < 10:
        time.sleep(10 - passed)

【讨论】:

  • 这是真的,先生,我希望它从循环的开头开始,以防万一出现错误,这是怎么回事?直到现在我还不明白这个错误:?我只想在发送后才睡觉,但是多个帖子是问题。
  • 这是异步运行的吗?似乎有多个版本同时运行,这可以用布尔值修复。
  • 我已经添加了布尔值,这样如果当前正在创建一个 POST,另一个不能运行。
  • 我非常怀疑请求库中存在问题。这是一个链接,可以帮助您进一步了解请求库,并帮助调试它。 :) pythonforbeginners.com/python-on-the-web/…
  • 你应该异步运行这些并让它们自己超时。这是一个链接,显示了如何使用 request 库异步运行 GET。您应该能够遵循相同的说明,但将它们更改为 POST。 :) stackoverflow.com/questions/9110593/…
【解决方案2】:
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 2020-10-08
  • 2015-07-08
  • 2020-04-25
相关资源
最近更新 更多