코딩 강의/유용한 스킬 없을까요

파이썬 크롤링으로 URL 이미지 저장하기

아미넴 2020. 10. 29.
반응형

#함께보면_좋은강의

sangminem.tistory.com/30

 

파이썬 크롤링을 활용하여 캔버스 이미지 저장하기

#함께보면_좋은강의 sangminem.tistory.com/83 Python(파이썬) 크롤링(Crawling)으로 URL 이미지 저장하기 #함께보면_좋은강의 sangminem.tistory.com/30 [Python(파이썬)] 크롤링(Crawling)을 활용한 캔버스(Canv..

sangminem.tistory.com

 

이번 포스팅에서는 이미지 URL을 알고 있는 경우 바로 가져올 수 있는 방법을 알려드리겠습니다.

 

샘플 URL은 아래와 같은 조선왕조실록에서 검색한 결과의 이미지 뷰어 페이지 입니다.

sillok.history.go.kr/popup/viewer.do?type=view&id=waa_10109001_001

 

조선왕조실록 : 원본 보기

태조실록 2권, 태조 1년 9월 1일 己卯 1번째기사 1392년 명 홍무(洪武) 1392년 명 홍무(洪武) 25년 삼사 좌사 이거인을 경사에 보내 황태자의 죽음을 애도하는 표문을 올리다

sillok.history.go.kr

 

기존처럼 canvas 태그 이미지를 가져오면 해상도가 떨어지는 문제점이 있어서

실제 다운로드 버튼을 눌렀을 때의 이미지를 가져오는 방법에 대해 알아 보겠습니다.

 

바로 이 부분을 클릭하는 것과 동일한 기능입니다.

 

먼저 크롬에서 F12를 눌러 개발자 모드에 진입합니다.

Sources 탭을 확인해 보면 viewer 밑에 URL이 하나 보입니다.

이 부분이 실제 다운로드 할 이미지 경로입니다.

 

Elements 탭에서 script 소스 부분을 살펴 보면 imgArr 배열 변수에

실제 이미지 파일명이 담겨있는 것을 확인할 수 있습니다.

이를 활용하여 소스를 짜 보겠습니다.

 

크롤링에 활용할 id가 담겨 있는 sample.txt 파일 내용입니다.

 

 

먼저 필요 모듈을 import 합니다.

import requests
import re
import os
import time
from bs4 import BeautifulSoup
from io import BytesIO

 

그리고 sample.txt 파일 내용을 읽습니다.

r = open('sample.txt', mode='rt', encoding='utf-8')
url_list_origin = []
file_name_list = []
idx = 0
for line in r:
    idx = idx + 1
    temp = line.split('^')
    url = re.sub('\n','',temp[0])
    if temp[0] != '기사 ID':
        if url not in url_list_origin:
            url_list_origin.append(url)
            temp1 = temp[1].split(' ')
            idx_len = 0
            if len(str(idx)) < 2 :
                idx_len = -2
            else :
                idx_len = -1*len(str(idx))
            file_name_list.append(re.sub('[\\/:*?"<>|]','',('조선왕조실록_'+temp1[0]+'_苧布_'+('0'+str(idx))[idx_len:]).strip()))
r.close()

url에 활용할 id를 가져와서 url_list_origin 배열에 담았고,

파일명을 알맞게 구성하여 file_name_list 배열에 담았습니다.

 

그리고 url을 호출하여 필요한 정보를 얻고 이미지를 가져와 보겠습니다.

index = 0
for url in url_list_origin:
    print(str(index)+':'+url)
    origin_url = 'http://sillok.history.go.kr/popup/viewer.do?type=view&id='+url
    res = requests.get(origin_url)
    soup = BeautifulSoup(res.content, 'html.parser')
    script = soup.select('script')
    start = script[9].string.find('imgArr = [')
    end = script[9].string.find('hlArr = [')
    temp_res = re.sub('\n', '',script[9].string[start:end]).strip()
    end2 = temp_res.find('];')
    temp_img_list = re.sub('"','',temp_res[10:end2])
    img_list = temp_img_list.replace('\\','').split(',')
    
    time.sleep(0.5)
    
    for i in range(len(img_list)) :
        file_name = file_name_list[index]
        if len(img_list) > 1:
            file_name = file_name +'_'+('0'+str(i+1))[-2:]+'.jpg'
        else :
            file_name = file_name + '.jpg'

        res2 = requests.get('http://sillok.history.go.kr/viewer/imageProxy.do?filePath=/s_img/SILLOK/' + img_list[i] + '.jpg')
        
        path = './images/'

        try:
            if not(os.path.isdir(path)):
                os.makedirs(os.path.join(path))
        except OSError:
            print("Failed to create directory!!!!!")

        with open(path+file_name, 'wb') as f:
            f.write(BytesIO(res2.content).read())
        
        time.sleep(1)
            
    index = index + 1

이미지 뷰어 페이지를 호출하여 필요한 정보를 얻습니다.

크롬 개발자 모드에서 확인한 imgArr 배열 내용이 10번째 script 태그에 담겨 있습니다.

'imgArr = [' 로 시작하여 'hlArr = ' 로 끝나는 부분을 가져와서

공백과 개행 문자를 제거하여 데이터를 정제하였습니다.

그리고 이미지가 여러 개 있을 경우를 고려하여 파일명을 만들어 주었습니다.

이후 과도한 엑세스로 인한 접근 제한을 피하기 위해 0.5초 간 대기 시간을 주었습니다.

실제 이미지 URL을 구성하여 호출하여 이미지 데이터를 가져왔고

BytesIO 모듈을 통해 바이너리 파일을 읽어와 파일로 저장할 수 있게 됩니다.

이미지 저장 후 마찬가지로 1초 간 대기 시간을 설정했습니다.

 

 

 

결과를 확인해 보겠습니다.

아주 깔끔하게 잘 저장된 것을 볼 수 있습니다.

반응형

댓글

💲 추천 글