Kaggle, ImageNet과 같은 사이트에서 데이터를 직접 받아오는 것이 아닌 필요한 데이터를 인터넷에서 크롤링하여 사용하는 것으로 결정했다.

크롤링 사이트도 구글에서 검색해 크롤링하는 것은 한계가 있어, 만개의 레시피 사이트에서 검색하는 결과를 크롤링하기로 했다.

구글 크롤링의 문제점 중 하나인 저화질의 이미지가 저장된다는 점은, 해당 이미지를 한번 클릭하면 고화질의 이미지가 나오기 때문에 그 이미지를 저장하는 방법으로 해결하려고 했었다. 하지만, 클릭하는 순간 url이 바껴서인지 이미지가 저장되지 않는 오류가 발생했다.

하지만 만개의 레시피 사이트는 크롤링하기도 더 쉽고 이미지 화질도 좋기 때문에 크롤링 사이트를 변경하게 되었다. 데이터의 양도 충분한 것 같았다.


코드 설명


1
2
3
4
5
from urllib.request import urlretrieve # 이미지를 저장할 때 사용
from urllib.parse import quote_plus # 한글을 컴퓨팅 언어로 변환
from bs4 import BeautifulSoup # 크롤링에 사용하기 위한 라이브러리
from selenium import webdriver # 구글 크롤링에 사용하기 위한 라이브러리
from webdriver_manager.chrome import ChromeDriverManager # 크롬 드라이버를 사용하기 위해서
c

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
food_list = ['김치찌개']
 
for name in food_list:# 반복문을 사용해 음식 종류 list안에 있는 음식별로 크롤링 할 수 있도록 설정
    
    # list에서 받아온 값을 넣은 url 생성
    # f'를 쓰는 이유는 검색어에 따라 url 포맷팅을 해주기 위함
    url = f'https://www.10000recipe.com/recipe/list.html?q={quote_plus(name)}&order=reco&page=1'
    
    driver = webdriver.Chrome(ChromeDriverManager().install()) # 구글 크롤링에 사용하기 위한 코드 (크롬 브라우저를 사용할 것임)
    driver.get(url) # url 변수를 크롬으로 열 수 있도록
    
          
    n = 1 # 크롤링 결과 사진에 숫자를 하나씩 증가시키기 위한 변수
    
    try:
        for page in range(1, 100):
            html = driver.page_source # 페이지의 elements 전부 가져오기
            soup = BeautifulSoup(html) # BeautifulSoup 사용
            
            imges = soup.findAll("a", {"class" : "common_sp_link"}) #  이미지 클래스의 값을 불러옴
    
            imgurl = [] # 이미지 url을 저장하기 위한 변수
    
            for i in imges:
                temp = i.img['src'] 
        
                if temp.endswith('png') is False: # png형식의 파일은 저장하지 않는다. 
                    imgurl.append(i.img['src']) # 이미지의 source 주소를 가져와 imgurl list에 추가한다                  
                    
            for i in imgurl:
                urlretrieve(i, "음식 사진/" + name + str(n) + ".jpg") # 크롤링한 사진에 1씩 값을 증가해 저장한다
                n += 1
            
            if page % 10 != 0: # 1, 2, 3, 4, 5, .... 11, 12, 13, ... 식으로 페이지를 넘겨야 하기 때문에 
                num = page % 10 + 1
                driver.find_element_by_xpath('//*[@id="contents_area_full"]/ul/nav/ul/li[%s]/a' %num).click() # 다음 페이지를 클릭한다.
                print(page)
            
            else: # 10번째가 되는 경우 다시 1번째로 돌아가야한다.
                driver.find_element_by_xpath('//*[@id="contents_area_full"]/ul/nav/ul/li[11]/a').click()
                print(page)
        
    except: # 이미지가 없는 경우 종료
        print("페이지의 끝입니다.")
        break
        
    driver.close()
cs

 

HTML이나 이것저것 공부를 좀 했더니 맨 처음보다 코드를 보는게 좀 더 쉬웠다.

페이지는 반복문을 사용해 1씩 늘리고, 나머지 연산자를 사용해서 같은 숫자가 반복되게 했다.

 

문제점

  • 20번째 페이지까지 갔다가 21번째 페이지로 넘어가지 않고 11번째 페이지로 돌아간다.
  • 21번째 페이지랑 11번째 페이지가 xPath 값이 같아서 그런 것 같다. 볼 수 있는 다른 방법이 있는 것 같은데.. 찾아봐야함
  • 모은 데이터 중에 쓸데없는 데이터가 가끔 보인다. 2차 분류를 통해서 글씨가 있는 이미지나, 쓸모 없는 이미지는 필터링해야 할 것 같다.

예정

  • 필터링 방법
  • 웹 공부
  • 구동 원리에 대한 이해

+ Recent posts