如何仅在使用请求下载图像时发生 "No Internet" 或 "Network Error" 之类的情况时才停止进程

How to halt process only when something like "No Internet" or "Network Error" occurs while downloading images using requests

我已经编写了一个脚本来下载图像并将其保存在提供的 url 目录中。它使用 requests 访问 DataFrame(CSV 文件)中给出的 URL,并使用 PILLOW 下载我目录中的图像。图片的名称是 url 在我的 CSV 中的索引号。如果有任何不可访问的坏 url,它只会增加计数器。每次我 运行 脚本时,它都会从最大索引开始下载到所需索引。我的代码工作正常。它是这样的:

import pandas as pd

import os
from os import listdir
from os.path import isfile, join
import sys

from PIL import Image

import requests
from io import BytesIO

import argparse


arg_parser = argparse.ArgumentParser(allow_abbrev=True, description='Download images from url in a directory',)

arg_parser.add_argument('-d','--DIR',required=True,
                       help='Directory name where images will be saved')

arg_parser.add_argument('-c','--CSV',required=True,
                       help='CSV file name which contains the URLs')

arg_parser.add_argument('-i','--index',type=int,
                       help='Index number of column which contain the urls')

arg_parser.add_argument('-e','--end',type=int,
                       help='How many images to download')

args = vars(arg_parser.parse_args())


def load_save_image_from_url(url,OUT_DIR,img_name):
    response = requests.get(url)
    img = Image.open(BytesIO(response.content))
    img_format = url.split('.')[-1]
    img_name = img_name+'.'+img_format
    img.save(OUT_DIR+img_name)
    return None


csv = args['CSV']
DIR = args['DIR']

ind = 0
if args.get('index'):
    ind = args['index']

df = pd.read_csv(csv) # read csv
indices = [int(f.split('.')[0]) for f in listdir(DIR) if isfile(join(DIR, f))] # get existing images

total_images_already = len(indices)
print(f'There are already {len(indices)} images present in the directory -{DIR}-\n')
start = 0
if len(indices):
    start = max(indices)+1 # set strating index
    
end = 5000 # next n numbers of images to download
if args.get('end'):
    end = args['end']

print(f'Downloaded a total of {total_images_already} images upto index: {start-1}. Downloading the next {end} images from -{csv}-\n')

count = 0
for i in range(start, start+end):
    if count%250==0:
        print(f"Total {total_images_already+count} images downloaded in directory. {end-count} remaining from the current defined\n")

    url = df.iloc[i,ind]
    try:
        load_save_image_from_url(url,DIR,str(i))
        count+=1

    except (KeyboardInterrupt, SystemExit):
        sys.exit("Forced exit prompted by User: Quitting....")

    except Exception as e:
        print(f"Error at index {i}: {e}\n")
        pass

我想添加一个功能,当发生 No internetconnection error 之类的事情时,它不会继续进行,而是停止进程 5 分钟。尝试 5 次后,即 25 分钟,如果问题仍然存在,则应退出程序而不是增加计数器。我想添加这个,因为如果没有互联网甚至 2 分钟,然后再次出现,它将 运行 通过循环并开始从该索引下载图像。下次如果我 运行 这个程序,它会认为丢失的 URL 是坏的,但只是没有互联网连接。

我该怎么做?

注意:很明显,我在考虑使用time.sleep(),但我想知道哪个错误直接反映在requests中的No InternetConnection Error ?一个是 from requests.exceptions import ConnectionError 如果我必须使用它,我如何使用它继续尝试相同的 i 计数器直到 5 次尝试,然后如果不成功,退出程序并在成功连接时,运行 常规循环。

我曾经使用过 google API,我偶尔会遇到无法上网、错误 423 或类似问题的情况。
我将整个代码保存在 try 块中,在 except 块中我应用了 .sleep() X秒。
这样我就不必搜索错误类型

To be noted, before doing it, make sure your code doesn't has any other type of error and will run smoothly, unless encounters with “No Internet” or “Network Error”

这是我解决问题的方法

import libs
basic operations
try:
  block 1
  block 2
  block_where_error_occurs
  block 3

except:
  print("Network error") 
  time.sleep(X-Seconds)

希望这对你也有帮助。如果此方法不能满足您的目的,请告诉我。

比睡眠更好的是使用指数退避。

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

retry_strategy = Retry(
    total=3,
    status_forcelist=[429, 500, 502, 503, 504],
    method_whitelist=["HEAD", "GET", "OPTIONS"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)

response = http.get(url)

这里可以配置如下参数:

  1. total=3 - 重试的总次数。
  2. backoff_factor - 它允许您更改进程在失败请求之间休眠的时间

回退系数的计算公式如下: {backoff factor} * (2 ** ({number of total retries} - 1))

所以 10 秒的退避将是 5、10、20、40、80、160、320、640、1280、2560 - 这些是后续请求之间的休眠时间