[연구실] 딥 러닝을 위한 이미지 크롤링

<이미지 크롤링>

딥러닝 모델에 넣기 위한 풍경화 이미지 데이터를 모으기 위해 이미지 크롤링이 필요\

참고 사이트: https://kimcoder.tistory.com/259

 

[크롤링, 예제 5] 이미지를 크롤링 해서 컴퓨터에 저장하기

4달만에 올리는 크롤링 포스팅인데 그 사이에는 개인 프로젝트, 웹 공부(spring, bootstrap)을 하느라 올릴 시간이 부족했던 것 같다. 오랜만에 소개할 예제는 이미지 크롤링이다. 이미지 크롤링 자체

kimcoder.tistory.com

 

 

1. 픽사베이(https://pixabay.com/ko/)에서 제공하는 무료 이미지를 이용한다. 

또한 크롤링을 위한 Python 라이브러리 BeautifulSoup을 이용

 

2. 해당 사이트의 url과 Html 구조를 파악해야한다. 

url 규칙은 다음과 같이

etc-image-0

search 다음에 검색할 단어, pagi 다음에 현재 페이지가 나타나게된다. 

 

Html에서 image url이 어디있는지 대략 파악을 하면, 다음과 같이 srcset 태그에 들어있는 것을 확인할 수 있다. 

etc-image-1

 

3. 어려웠던 점은 image의 tag가 어떤식으로 되어 있는지 파악하기 어려운 점이 있었다.

위에서 대략적으로 파악한 tag외에 다양한 tag로 image url이 존재하여 그렇다. 

이후 'data-lazy-srcset'이라는 속성값을 파악하였지만 이래도 실패하였다. 

 # get 한 image에 srcset이라는 속성이 없다면 -> data-lazy-srcset
        if img.get("src") == None :
            if img.get('data-lazy-src') == None:
                srcset = img.get('data-lazy-srcset')
            else:
                srcset = img.get('data-lazy-src')
        else:
            srcset = img.get('src')

 

4. 왜냐하면 위의 코드에서 src가 None이 아니면 무조건 src로 하도록 하였는데 해당 src 속성 중 동적 이미지 /static에 대한 값이 존재하였기  때문이다. 

 

5. 따라서, 다음과 같이 코드를 바꾼다. 

# get 한 image에 srcset이라는 속성이 없다면 -> data-lazy-srcset
        if img.get("src") == None or img.get("src").startswith('/static') :
            if img.get('data-lazy-src') == None:
                srcset = img.get('data-lazy-srcset')
            else:
                srcset = img.get('data-lazy-src')
        else:
            srcset = img.get('src')

 

전체 코드

from bs4 import BeautifulSoup as bs
from urllib.request import urlopen
from urllib.request import Request
import urllib.request
from urllib.parse import quote_plus
import os
import sys
from selenium import webdriver
from time import sleep

# 검색어 및 이미지 개수 설정
# keyword = input('검색어 입력:')
# crawl_num = int(input('크롤링할 이미지 개수 입력: '))

keyword = "풍경"
crawl_num = 100

pages = int((crawl_num-1)/100)+1 # pages 개수
img_count = 0 # image count
finish = False

# image 저장 경로
path = './data/train/'

# 크롬 드라이버 설정
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('lang=ko_KR')
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36")
driver = webdriver.Chrome('./chromedriver.exe',chrome_options=chrome_options)

for i in range(1, int(pages)+1):
    # 구글 웹페이지에 로드
    driver.get('https://pixabay.com/images/search/' + keyword + '/?pagi=' + str(i))
    sleep(1)
    
    html = driver.page_source
    soup = bs(html, "html.parser")

    imgs = soup.select('.link--h3bPW img') #요소 선택

    #print(imgs)

    # 마지막 이미지 여부
    lastPage = False
    if len(imgs) != 100:
        lastPage = True

    for img in imgs:
        #if img.get("src") != None:
        #    continue

        # 이미지 개수 증가
        img_count += 1

        srcset = ""
        # get 한 image에 srcset이라는 속성이 없다면 -> data-lazy-srcset
        if img.get("src") == None or img.get("src").startswith('/static') :
            if img.get('data-lazy-src') == None:
                srcset = img.get('data-lazy-srcset')
            else:
                srcset = img.get('data-lazy-src')
        else:
            srcset = img.get('src')

        print("srcset: " + srcset)

        if len(srcset):
            src = str(srcset).split()[0] # 가장 작은 이미지 경로 추출
            print(str(img_count) + '번째 이미지 경로 src')
            print(src)

            # user-agent 헤더 request
            req = Request(src, headers={'User-Agent': 'Mozilla/5.0'})

            try:
                imgUrl = urlopen(req).read()
                with open(path + 'train' + str(img_count)+'.jpg','wb') as f:
                    f.write(imgUrl) # 파일 저장
            except urllib.error.HTTPError:
                print('error')
                sys.exit(0)
        
        # 입력된 이미지 개수만큼 크롤링 했을 경우
        if img_count == crawl_num:
            finish = True
            break
    
    if finish or lastPage:
        break

print('크롤링된 이미지 cont' + str(img_count))