8. Scrapy Logging > 8-1. Scrapy Log_LEVEL을 통한 오류 찾기

Scrapy Log_LEVEL을 통한 오류 찾기

Scrapy를 실행했을 때 출력되는 로그는 처음에는 신기하지만, 장황한 탓에 오류 메세지를 찾기 힘들게 합니다.

  • 순간포착 오류 메세지 찾기 🔍

이러한 고민은 settings.py에 LOG_LEVEL 설정을 추가해 해결할 수 있습니다.

💡 개념잡기: LOG_LEVEL 설정

LOG_LEVEL은 표시할 메세지의 수준을 결정합니다. Scrapy의 표준적인 LOG_LEVEL은 총 5가지입니다.

  1. CRITICAL — 최고 심각도
  2. ERROR — 추천
  3. WARNING
  4. INFO
  5. DEBUG — 최저 심각도, 기본 설정과 동일

로그 수준을 WARNING으로 설정하면 CRITICAL, ERROR, WARNING 로그만 출력되고, DEBUG로 설정하면 모든 로그가 출력됩니다. 수준을 변경하면서 차이를 파악해보세요.

📖 참고하기: 로깅(Logging)이란?

로깅이란 로그를 기록하는 행위를 말합니다.

프로그래밍에서 로그(Log)는 운영체제나 소프트웨어가 실행하는 도중 발생하는 이벤트, 혹은 각기 다른 사용자의 통신 소프트웨어 간의 메세지를 의미합니다.

출처: [위키백과] 로그파일

#settings.py
LOG_LEVEL = 'ERROR'    # 직접 입력

0

오류 메세지를 찾기 매우 쉬워졌네요 😆

이외에도 출력되는 print문을 보고 어느 부분이 잘못됐는지 파악할 수 있습니다. 3주차의 st11_best.py에 작성했던 print문 3개를 기억하시나요?

  • 기억이 나지 않는다면...

    #st11_best.py: 최종
    import scrapy
    from st11.items import St11Item
    
    class St11BestSpider(scrapy.Spider):
        name = 'st11_best'
    
        def start_requests(self):
            yield scrapy.Request(url="https://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo=0",
                                 callback=self.parse_mainpages)
            
        def parse_mainpages(self, response):
            print("parse_mainpages")
            category_names = response.css(quiz:메인 카테고리명의 css 선택자 경로).getall()
            for idx, name in enumerate(category_names):
                yield scrapy.Request(url="https://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo="+str(idx), 
                                     callback=self.parse_items, 
                                     meta={'maincategory_name':category_names[idx], 'subcategory_name':'All'})
            for idx, name in enumerate(category_names):
                yield scrapy.Request(url="https://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo="+str(idx), 
                                     callback=self.parse_subcategory, 
                                     meta={'maincategory_name':category_names[idx],'index':idx}
                                    )
        
        def parse_subcategory(self, response):
            print('parse_subcategory', response.meta['maincategory_name'])        
            subcategory_names = response.css(quiz:서브 카테고리명의 css 선택자 경로).getall()
            subcategory_lists = response.css('div.sub_category_box li a::attr("onclick")').re('\(.*\)')
            subcategory_idcs = []
            for i in subcategory_lists:
                if i[2] == ',':
                    subcategory_idcs.append((int(i[1]),int(i[3:-1])))
                else:
                    subcategory_idcs.append((int(i[1:3]),int(i[4:-1])))
            
            for idx, sub in enumerate(subcategory_idcs):
                if sub[0] == response.meta['index']:
                    yield scrapy.Request(url="https://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo=" + str(sub[0]) + "&dispCtgrNo=" + str(sub[1]), 
                                         callback=self.parse_items,
                                         meta={'maincategory_name':response.meta['maincategory_name'], 
                                                                          'subcategory_name':subcategory_names[idx]}
                                        )
                else:
                    continue
    
        # 메인 카테고리, 서브 카테고리의 정보를 모두 크롤링하는 메서드. 코드는 처음과 동일
        def parse_items(self, response):
            print('parse_items', response.meta['maincategory_name'], response.meta['subcategory_name'])
            best_items = response.css('div.viewtype.catal_ty')
            for idx, item in enumerate(best_items[1].css('li')):
                doc = St11Item()
                
                ranking = idx + 1
                title = item.css(quiz:베스트 상품이름의 css 선택자 경로).get().strip()
                ori_price = item.css(quiz:할인전가격의 css 선택자 경로).get()
                dis_price = item.css(quiz:할인된가격의 css 선택자 경로).get()
                
                if ori_price == None:
                    ori_price = dis_price
                ori_price = ori_price.replace(',','').replace('원','')
                dis_price = dis_price.replace(',','').replace('원','')
                
                doc['main_category_name'] = response.meta['maincategory_name']
                doc['sub_category_name'] = response.meta['subcategory_name']
                doc['ranking'] = ranking
                doc['title'] = title
                doc['ori_price'] = ori_price
                doc['dis_price'] = dis_price
         
                yield doc
    

'parse_mainpages '와 'parse_subcategory'은 출력되는데 'parse_items'가 보이지 않는다면, parse_items 메서드에 문제가 있다고 추측할 수 있는 것이죠. 메서드와 반복문 중간중간 print문을 넣고 실행해, 코드를 잘 작성하고 있는지 확인하는 것을 추천드립니다 👨‍🔧

마지막으로 업데이트 된 날짜:
2022년 11월 18일