【问题标题】:Python: Response code returns 200 even when internet is turned off?Python:即使关闭互联网,响应代码也会返回 200?
【发布时间】:2021-08-09 16:36:09
【问题描述】:

一直在尝试创建一个循环,即使网络连接中断(try/except 块)也会继续迭代。在大多数情况下,它有效。但是在执行过程中,当我关闭 Wi-Fi 后测试响应代码时,它仍然返回 200。 似乎无法理解为什么会这样。我的意思是,200 表示没有 Wi-Fi 连接就无法成功获取请求,对吧?我读到响应码200是默认缓存的,是这个原因吗?我能做些什么来克服这个问题? 不能因为使用了后一种请求方法,对吗? 这是主要代码。

base = datetime.datetime.today()
date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
date_str = [x.strftime("%d-%m-%Y") for x in date_list]

loop_starts = time.time()
for INP_DATE in date_str:
    try:
        # API to get planned vaccination sessions on a specific date in a given district.
        URL = f"https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict?district_id=" \
              f"512&date={INP_DATE}"
        response = requests.get(URL, headers=browser_header)
        response.raise_for_status()

    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("OOps: Something Else", err)

    finally:
        print(f'Response code: {response.status_code}') #Why do you always return 200?!

        #code not important to the question
        if response.ok:
            resp_json = response.json()
            # read documentation to understand following if/else tree
            if resp_json["sessions"]:
                print("Available on: {}".format(INP_DATE))
                if print_flag == 'y' or print_flag == 'Y':
                    for center in resp_json["sessions"]:  # printing each center
                        if center["min_age_limit"] <= age:
                            print("\t", "Name:", center["name"])
                            print("\t", "Block Name:", center["block_name"])
                            print("\t", "Pin Code:", center["pincode"])
                            #   print("\t", "Center:", center)
                            print("\t", "Min Age:", center['min_age_limit'])
                            print("\t Free/Paid: ", center["fee_type"])
                            if center['fee_type'] != "Free":
                                print("\t", "Amount:", center["fee"])
                            else:
                                center["fee"] = '-'
                            print("\t Available Capacity: ", center["available_capacity"])
                            if center["vaccine"] != '':
                                print("\t Vaccine: ", center["vaccine"])
                            else:
                                center["vaccine"] = '-'
                            print("\n\n")

                            # Sending text message when availability of vaccine >= 10
                            # Creating text to send to telegram

                            txt = f'Available on: {INP_DATE}\nName: {center["name"]}\nBlock ' \
                                  f'Name: {center["block_name"]}\nPinCode: {center["pincode"]}\n' \
                                  f'Min Age: {center["min_age_limit"]}\nFree/Paid: {center["fee_type"]}\n' \
                                  f'Amount: {center["fee"]}\nAvailable Capacity: {center["available_capacity"]}\n' \
                                  f'Vaccine: {center["vaccine"]}\n\nhttps://selfregistration.cowin.gov.in/'
                            if center["available_capacity"] >= 10:
                                to_url = 'https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=' \
                                         'HTML'.format(token, chat_id, txt)
                                resp = requests.get(to_url)
                                print('Sent')
            else:
                print("No available slots on {}".format(INP_DATE))
        else:
            print("Response not obtained.") #Should output when net is off.

        time.sleep(25)  # Using 7 requests in 1 second. 100 requests per 5 minutes allowed. You do the math.
        #  timing the loop
        now = time.time()
        print("It has been {} seconds since the loop started\n".format(now - loop_starts))

【问题讨论】:

  • 肯定是因为finally无论如何都会执行,所以承认你在请求过程中抛出了异常,函数`requests.get(URL, headers=browser_header)`还没有返回,所以 response = 还没有被执行,所以你仍然有循环的前一次迭代的值,你当然想要在每个异常中 continue 并且没有 finally
  • @allan.simon,实际上它会保留之前的status_code,即使在退出之后。解决方案 (种类) 是在每个请求之前将 status_code 设为空 response.status_code = 0
  • @OlvinR​​oght 在程序停止并重新启动后,“退出后”是什么意思?问题中似乎没有说明,这意味着wifi在执行期间被切断了?
  • @OlvinR​​oght 编辑状态码感觉怪怪的,不应该在这里finally,因为您不想在已经显示的错误消息之外显示任何内容?
  • @allan.simon,我的意思是如果你发送请求并且一次迭代会引发异常,response 对象根本不会被更新。可以设置response = None

标签: python python-requests response httpresponse http-response-codes


【解决方案1】:

像这样重写你的代码

  1. 在网络异常的情况下没有覆盖响应,所以response是之前的值
  2. finally 是陷阱,因为即使捕获到异常也会执行代码,这不是您想要的
  3. 在您的异常中使用continue 重试
base = datetime.datetime.today()
date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
date_str = [x.strftime("%d-%m-%Y") for x in date_list]

loop_starts = time.time()
for INP_DATE in date_str:
    try:
        # API to get planned vaccination sessions on a specific date in a given district.
        URL = f"https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict?district_id=" \
              f"512&date={INP_DATE}"
        response = requests.get(URL, headers=browser_header)
        response.raise_for_status()

    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
        continue
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
        continue
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
        continue
    except requests.exceptions.RequestException as err:
        print("OOps: Something Else", err)
        continue

    # will now only been displayed when you DO have a 200
    print(f'Response code: {response.status_code}') #Why do you always return 200?!

    #code not important to the question
    resp_json = response.json()
    # read documentation to understand following if/else tree
    if not resp_json["sessions"]:
        print("No available slots on {}".format(INP_DATE))
        continue

    print("Available on: {}".format(INP_DATE))
    if print_flag != 'y' and print_flag != 'Y':
        continue

    for center in resp_json["sessions"]:  # printing each center
        if center["min_age_limit"] > age:
            continue
        print("\t", "Name:", center["name"])
        print("\t", "Block Name:", center["block_name"])
        print("\t", "Pin Code:", center["pincode"])
        #   print("\t", "Center:", center)
        print("\t", "Min Age:", center['min_age_limit'])
        print("\t Free/Paid: ", center["fee_type"])
        if center['fee_type'] != "Free":
            print("\t", "Amount:", center["fee"])
        else:
            center["fee"] = '-'
        print("\t Available Capacity: ", center["available_capacity"])
        if center["vaccine"] != '':
            print("\t Vaccine: ", center["vaccine"])
        else:
            center["vaccine"] = '-'
        print("\n\n")

        # Sending text message when availability of vaccine >= 10
        # Creating text to send to telegram

        txt = f'Available on: {INP_DATE}\nName: {center["name"]}\nBlock ' \
              f'Name: {center["block_name"]}\nPinCode: {center["pincode"]}\n' \
              f'Min Age: {center["min_age_limit"]}\nFree/Paid: {center["fee_type"]}\n' \
              f'Amount: {center["fee"]}\nAvailable Capacity: {center["available_capacity"]}\n' \
              f'Vaccine: {center["vaccine"]}\n\nhttps://selfregistration.cowin.gov.in/'
        if center["available_capacity"] >= 10:
            to_url = 'https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=' \
                     'HTML'.format(token, chat_id, txt)
            resp = requests.get(to_url)
            print('Sent')

    time.sleep(25)  # Using 7 requests in 1 second. 100 requests per 5 minutes allowed. You do the math.
    #  timing the loop
    now = time.time()
    print("It has been {} seconds since the loop started\n".format(now - loop_starts))

【讨论】:

    【解决方案2】:

    正如其他人评论和回复的那样,finally 在这里不合适。 allan.simon 提供了一个在异常处理程序中使用continue 的解决方案。这当然是一个很好的解决方案。

    另一种解决方案(不一定更好):将finally 替换为elsetry-statement 中的 else 子句“如果控制流离开 try 套件,没有引发异常,并且没有执行 return、continue 或 break 语句,则执行。” (引用文档)。这正是您在此处尝试使用 finally 所做的事情。

    【讨论】:

    • 应该else块。一堆continue 语句通常是错误代码的标志。我已经applied 对代码进行了一些重构,但实在没有时间详细解释。如果您有时间,可以将此代码添加到您的答案中并附上一些注释。
    • @OlvinR​​oght 不一定。 Early continue 是 Early Return 的一种变体,可以使代码更容易理解;参见例如medium.com/swlh/return-early-pattern-3d18a41bba8
    • 是和不是。 try ... except 中的一个 else 块比每个异常处理程序中的 continue 语句要好得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2017-01-29
    • 2014-10-08
    • 2019-04-02
    • 1970-01-01
    • 2017-09-07
    相关资源
    最近更新 更多