728x90

연속적으로 계속해서 이미지의 링크를 통해 이미지를 다운받다보면,

링크에 접속하여 url을 여는 시간이 지나치게 오래 걸리거나 긴 시간 끝에 결국 다운로드에 실패하는 경우가 많다.

모두 다운받기보다는 한정된 시간 안에 최대한 많은 양의 이미지를 다운받는 것이 목표라면? timeout 설정을 아는 것이 좋다.

 

이미지의 링크에 접속하는 방법은 urllib.request의 urlopen과 requests의 get 메소드를 통해 가능하다.

그런데 유의할 점! 이 두가지 방법중 requests의 get 메소드만 timeout설정을 가지고 있기 때문에 만약에  timeout 설정을 하고 싶다면 requests의 get 메소드를 통해 image url을 읽어들여야 한다.

 

아래와 같은 함수를 작성하여 timeout을 설정하고 url을 가져오는 시간이 너무 오래 걸릴 경우(아래 코드에서 timeout인자(초단위)보다 긴 시간이 소요될 경우) url을 통해 이미지를 가져오는 것은 중단되고 바로 다음 업무를 수행하게 할 수 있다.

import multiprocessing
import requests

def getRequest(func, args, timeout):
    manager = multiprocessing.Manager()
    return_dict = manager.dict()

    def function(return_dict):
        return_dict['value'] = func(*args)

    p = multiprocessing.Process(target=function, args=(return_dict,))
    p.start()
    p.join(timeout)

    if p.is_alive():
        p.terminate()
        p.join()
        raise TimeoutError
    else:
        return return_dict['value']

이렇게 작성한 timeout코드를 실제 코드에 적용하여 이미지를 가져오는 시간이 너무 오래 걸리는 pass하고 오래 걸리지 않으면 이미지를 읽어오는 코드를 만들어보면 아래와 같다.

from PIL import Image
from io import BytesIO

# 테스트로 활용할 urls
urls = [
    "http://www.stardailynews.co.kr/news/photo/202002/266018_302177_3442.png",
    "https://dispatch.cdnser.be/cms-content/uploads/2020/04/09/f8508e74-2257-4030-842e-3840076b6274.jpg",
    "http://storage.googleapis.com/piclick-ai-kr/KR/2020/03/24/21/4/7140292.jpg",
    "https://file.mk.co.kr/meet/neds/2020/04/image_readmed_2020_370536_15863911794156017.jpg",
    "https://menu.mt.co.kr/moneyweek/thumb/2020/04/09/06/2020040907518077096_1.jpg",
    "https://file.mk.co.kr/meet/neds/2020/04/image_readtop_2020_372308_15864010004156729.jpg",
    "https://file.mk.co.kr/meet/neds/2020/04/image_readtop_2020_373441_15864105574156995.png",
    "https://file.osen.co.kr/article/2020/03/27/202003272226778356_5e7e0901decc2.jpg",
    "https://file.osen.co.kr/article/2020/02/20/202002202126776740_5e4e7cedc80ad.jpg"
]

for url in urls:
    try:
        res = getRequest(requests.get, args=(url,), timeout=0.5)
        img = Image.open(BytesIO(res.content))
        print(img.size, "Load Image---")
    except:
        print("timeout")

이 코드들이나 timeout에 대한 정보는 이 블로그를 참고하였다.

 

728x90