네이버 이미지 크롤링(수집)

ggydo59·2023년 3월 18일
0

음식이미지 크롤링

def Driver():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    #options.add_argument("headless")
    options.add_argument('--start-fullscreen')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    wd = webdriver.Chrome(options = options)
    return wd

# 베이스 URL과 상업적 이용 가능 옵션
def make_url(word):
    base_url = 'https://search.naver.com/search.naver?sm=tab_hty.top&where=image&query='
    ccl = '&res_fr=0&res_to=0&sm=tab_opt&color=&ccl=2&nso=so%3Ar%2Ca%3Aall%2Cp%3Aall&recent=0&datetype=0&startdate=0&enddate=0&gif=0&optStr=&nso_open=1&pq='
    return base_url + word + ccl

# 해당하는 폴더가 없을 경우 생성해주는 함수
def makedirs(path): 
   try: 
        os.makedirs(path) 
   except OSError: 
       if not os.path.isdir(path): 
           raise

# 찾을 목록이 담긴 dictionary
search_dict = {
        '건강식단': ['샐러드','고구마요리','닭가슴살','연어음식','오트밀'],
        '밥류' : ['볶음밥','덮밥','한정식','돈까스','오므라이스'],
        '면류' : ['라면','짜장면','짬뽕','파스타','냉면', '국수'],
        '패스트푸드' : ['햄버거','감자튀김','피자','치킨','떢볶이'],
        '디저트류' : ['카페음료','와플','아이스크림','조각케이크','쿠키','빙수']}

def save_images(image_url, paths, file_name, i):
    import base64
        
    if 'data:' in str(image_url):
        pass
    else:
        t= urlopen(image_url).read()
        file = open(os.path.join(paths, file_name+'_'+str(i)+".gif"), 'wb')
        file.write(t)

def naver_crawl(image_numbers):
    wd = Driver()
    wd.implicitly_wait(3)
    for meal in search_dict:
        for food in search_dict[meal]:
                # 음식에 해당하는 검색어를 입력한 페이지 출력
                print(f"------------------ Start {meal} / {food} ----------------------")
                wd.get(make_url(food))
                time.sleep(2)
                for i in range(1,image_numbers+1):
                    time.sleep(2)
                    # i에 해당하는 이미지가 없을 경우 PASS
                    try:
                        # image url 추출
                        images= wd.find_elements(By.XPATH, f'//*[@id="main_pack"]/section[2]/div/div[1]/div[1]/div[{i}]/div/div[1]/a/img')
                        save_path = os.path.dirname(os.path.abspath(os.getcwd()))
                        makedirs(save_path)
                        src = images[0].get_attribute('src')
                        save_images(str(src), save_path, f'{meal}_{food}_', i)
                        
                        # 이미지가 10개가 넘어갈때 마다 PAGE_DOWN
                        if i % 10 == 0:
                            body = wd.find_element(By.XPATH,'//body').send_keys(Keys.PAGE_DOWN)
                            time.sleep(3)
                    except:
                        print(f"No element in {i}")
                        continue
                print(f"------------------ end {meal} / {food} ----------------------")
    wd.close()
    print("End_crawling")
  • 그 때 당시에 기억으로는 중간중간에 없는 div번호가 있어서 예외처리를하고 없는 번호가 뭔지 출력하게끔 진행했다.
  • 위 코드를 간단히 요약하자면 원하는 검색어의 이미지 페이지에서 이미지 열 개마다 스크롤을 내리면서 이미지를 수집한다.
  • 이미지저장은 실행한 위치의 상위폴더에서 음식이름의 폴더로 저장함.

증명사진 네이버 API 사용 크롤링

  • 네이버 API는 공식문서를 참고하는 것이 가장 좋다.
  • 네이버 API
import os
import sys
import urllib.request
import environ
import json

# 환경변수 관리, django에서 쓰던방법인데 편해서 자주 사용
# pip install python-environ으로 설치, django 설치 필수
image_urls = []
BASE_DIR = os.getcwd()
env = environ.Env(DEBUG=(bool, True))
environ.Env.read_env(env_file=os.path.join(BASE_DIR, '.env'))  

# 네이버 api app을 만들면 client id, secret_key를 발급해주는데 매 요청시 헤더에 넣어줘야한다.
client_id = env("NAVER_ID") 
client_secret = env("NAVER_APIKEY")
encText = urllib.parse.quote("증명사진")

# 해봤는데 천 개이상 크롤링이 불가해서, 학습용으로 수집할 데이터로는 부적합.
# 최대 1000개 까지 가능 매일매일 주식 정보나 블로그 최근 트렌드 그런용도로만 수집가능한듯
for i in range(10):
    page_num = 1+ (i*100)
    url = "https://openapi.naver.com/v1/search/image?query=" + encText + '&display=100'+ '&start=' + str(page_num) # JSON 결과
    # url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
    request = urllib.request.Request(url)
    request.add_header("X-Naver-Client-Id",client_id)
    request.add_header("X-Naver-Client-Secret",client_secret)
    response = urllib.request.urlopen(request)
    rescode = response.getcode()

    if(rescode==200):
        response_body = response.read()
        images = response_body.decode('utf-8')
        images = json.loads(images)
        for image in images['items']:
            image_urls.append(image['link'])          
    else:
        print("Error Code:" + rescode)

print(len(image_urls))
  • 아무래도 다시 셀레니움으로 수집해야 될듯 하다.

풀 코드

참고

profile
데이터엔지니어입니다.

0개의 댓글