Programming Language/Python

[Python] image url을 사용하여 이미지 다운로드

new_challenge 2020. 4. 9. 22:49
반응형

이번 포스팅은 파이썬에서

이미지 주소를 가지고 이미지 파일로 다운로드하는 

방법들에 관한 튜토리얼입니다.

 

 

 

 

인터넷에 존재하는 이미지 파일을 다운로드 하는 다양한 방식

아래 적혀 있는 소요 시간은 이미지 파일의 용량에 따라 달라짐

 

 

 

 

이미지를 저장해서 사용

아래 2가지 방법은 이미지를 저장하여 사용하는 방법 이다

python으로 curl 요청을 보내거나 urllib 라이브러리를 사용하는 방법

python에서 curl 요청

import os
import time

# 다운받을 이미지 url
url = "https://dispatch.cdnser.be/cms-content/uploads/2020/04/09/a26f4b7b-9769-49dd-aed3-b7067fbc5a8c.jpg"

# time check
start = time.time()

# curl 요청
os.system("curl " + url + " > test.jpg")

# 이미지 다운로드 시간 체크
print(time.time() - start)

# 저장 된 이미지 확인
img = Image.open("test.jpg")

>> python 내부에서 직접 command로 curl 요청을 보내 이미지 다운로드 하는 방식

>> curl "이미지 주소" > "저장 될 이미지 파일 이름" 

>> 대략 0.05s 소요 (이미지 크기에 따라 다름)

 

urllib.request.urlretrieve

import urllib.request
import time

# 다운받을 이미지 url
url = "https://dispatch.cdnser.be/cms-content/uploads/2020/04/09/a26f4b7b-9769-49dd-aed3-b7067fbc5a8c.jpg"

# time check
start = time.time()

# 이미지 요청 및 다운로드
urllib.request.urlretrieve(url, "test.jpg")

# 이미지 다운로드 시간 체크
print(time.time() - start)

# 저장 된 이미지 확인
img = Image.open("test.jpg")

>> urllib.request.urlopen : 이미지 저장 없이 바로 사용

>> urllib.reqeust.urlretrieve("이미지 주소", "저장 할 파일이름") : 이미지 저장해서 사용

>> 대략 0.03s 소요 (이미지 크기에 따라 다름)

 

 

이미지 저장 없이 바로 사용

아래 2가지 방법은 이미지를 저장하여 사용하는 방법 이다

python의 urllib 라이브러리를 사용 혹은 request.get을 하는 방법

urllib.request.urlopen

from urllib import request
import time

url = "https://dispatch.cdnser.be/cms-content/uploads/2020/04/09/a26f4b7b-9769-49dd-aed3-b7067fbc5a8c.jpg"

# time check
start = time.time()

# request.urlopen()
res = request.urlopen(url).read()

# 이미지 다운로드 시간 체크
print(time.time() - start)


# Image open
img = Image.open(BytesIO(res))

>> 이번엔 urlib을 사용해서 이미지를 open하는 방법

>> urllib.request.urlopen을 사용하여 이미지 데이터를 읽음

>> 대략 0.03s 소요 (이미지 크기에 따라 다름)

 

 

request.get 사용

import requests
from io import BytesIO
from PIL import Image
import time

# 다운받을 이미지 url
url = "https://dispatch.cdnser.be/cms-content/uploads/2020/04/09/a26f4b7b-9769-49dd-aed3-b7067fbc5a8c.jpg"

# time check
start = time.time()

# request.get 요청
res = requests.get(url)

# 이미지 다운로드 시간 체크
print(time.time() - start)

#Img open
img = Image.open(BytesIO(res.content))

>> request.get : 이미지주소를 사용하여 이미지 데이터를 가져올 수 있음

>> 결과.content에 이미지의 바이트가 담겨 있음

>> 데이터를 BytesIO로 읽은 뒤 이미지 Open

>> 대략 0.04s 소요 (이미지 크기에 따라 다름)

 

 

[참고] request.get Timeout

이미지 다운로드 시 오래 걸리는 이미지에 대해 타임 아웃 기능을 추가하고 자 하는 경우

기본적으로 request.get 함수에서 제공하는 timeout 기능은 전체 프로세스에 대해 측정 하는 것이 아님

아래 이미지 참고(공식문서에서 가져온 내용)

 

>> 위 설명에서 보면 timeout 기능은 전체 응답 다운로드에 대한 제한이 아니고, 서버상의 요청에서의 타임아웃에 에러를 발생시키는 timeout이다. 따라서 서버 요청은 잘 되었으나, 이미지의 용량이 커서 전체 프로세스 시 시간이 오래 걸리는 경우 발생

 

 

[참고] 새로 추가 한 Timeout

기본적으로 제공해주는 기능에서는 활용이 불가능하고, 타임아웃 기능을 위해 추가적인 코딩이 필요

파이썬의 멀티프로세싱 기능을 활용해 타임아웃 구현

 

// Timeout Multiprocessing 함수

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']

 

// 실제 요청

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을 초과하면 pass, 그렇지 않으면 이미지를 읽는다

반응형