15. 쿠팡 데이터 수집, selenium을 통한 파이썬 크롤링(feat. 쿠팡 크롤링 & 학습용 & 쿠팡 우회 뚫기)

오늘은 쿠팡에서 데이터를 수집하는 방법에 대해서 알아보도록 하겠습니다. 쿠팡의 유능한 개발자분들이 왠만한 방법은 모두 막아두셨기 때문에 우회하는데 생각보다 시간이 걸렸습니다. 오로지 자연어 처리 전문가로써 크롤링을 학습하고, 익숙해지기 위해 진행한 프로젝트이니 악의적으로 데이터를 수집하시면 절대 안됩니다.

쿠팡 데이터 수집 개요

자연어 처리 전문가가 이러한 연습을 해야하는 이유는 인터넷에 수많은 데이터들이 있습니다. 이를 합법적으로 수집하여 정제하고 인공지능에 학습는 업무를 진행할 때도 있습니다. 그런데, 이를 수집할 때 매우 오래걸리면 업무 퍼포먼스가 나지 않는 것은 당연하겠죠?

그렇기에 평상시에 생각날때 한번씩 연습을 하고 업데이트 된 내용들이 있는지 지속적으로 체크하는 습관을 가지고 있습니다.

기술은 언제나 업데이트 되고, 발전하기에 지속적인 follow up이 중요하다고 생각합니다.

그럼 이제 시작해보도록 하겠습니다.

쿠팡 데이터 수집 코드

필요한 라이브러리 import

from webdriver_manager.chrome import ChromeDriverManager 
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import NoSuchElementException
import time 

from openpyxl import Workbook

필요한 라이브러리를 불러와줍니다.

최근 selenium이 많이 업데이트 되었기 때문에 예전에 셀레니움을 사용하시던 분들은 공식문서를 한번 살펴보실 필요가 있습니다.

저는 제가 수집하고 싶은 카테고리를 아래와 같이 리스트로 만들었습니다.

카테고리 리스트화

물론 이를 수집하는 것도 코드로 구성하시면 되는데, 저는 이렇게 영어로 리스트로 작성했습니다.

original_list = [
    "food", "household_items", "beauty", "electronics_digital", "home_kitchen",
    "maternity_baby", "pet_supplies", "toys", "automotive", "stationery_office", "sports",
    "books_music_movies", "health_supplements", "women_fashion", "men_fashion",
    "kids_baby_fashion", "unisex_clothing"
]

카테고리 & code -> dict화

그 다음 product_code를 dictionary로 만들어줍니다. 해당 코드는 url를 자세히 관찰해보시면 얻으실 수 있습니다.

product_code = {'food': 194276, 'household_items': 115573, 'beauty': 176422, 'interior': 184455, 'electronics_digital': 178155, 'home_kitchen': 185569, 'maternity_baby': 221834, 'pet_supplies': 115574, 'toys': 317679, 'automotive': 183960, 'stationery_office': 177195, 'sports': 317678, 'books_music_movies': 317677, 'health_supplements': 305698, 'women_fashion': 186664, 'men_fashion': 186969, 'kids_baby_fashion': 213101, 'unisex_clothing': 502893}

위 정보를 활용하여 각 카테고리별 url_list를 만들어줍니다.

url_list = [] 
for lis in original_list:
    key = product_code[lis] 
    raw_url = f"https://www.coupang.com/np/categories/{key}?listSize=120&brand=&offerCondition=&filterType=&isPriceRange=false&minPrice=&maxPrice=&page="
    url_list.append(raw_url)

Selenium 이란?

이제 Selenium options를 선택해주도록 하겠습니다.

selenium과 options이 무엇인지 모르는 분들을 위해 잠시 설명을 드리겠습니다.


Selenium은 웹 브라우저를 자동화하고 웹 애플리케이션을 테스트하는 데 사용되는 파이썬 라이브러리입니다. Selenium을 사용할 때 웹 브라우저의 동작을 커스터마이징하고 제어하는 방법 중 하나로 “Options”을 활용할 수 있습니다. Options는 웹 브라우저의 동작을 설정하는 데 사용되며, 다양한 옵션을 통해 웹 드라이버의 동작을 변경하고 개인화할 수 있습니다.

일반적으로 Selenium은 웹 드라이버를 초기화할 때 Options를 설정하여 웹 브라우저의 동작을 사전에 지정할 수 있습니다. 주요 브라우저인 Chrome, Firefox, Edge 등은 각각 자체 Options를 제공합니다. 저는 Chrome을 사용하였습니다. 아래는 각 브라우저에 대한 Options에 대한 간단한 설명입니다:

  1. Chrome Options: Chrome 브라우저를 자동화할 때 사용되는 옵션입니다. 일반적으로 다음과 같은 용도로 활용됩니다:
    • 브라우저 창 크기 설정
    • 사용자 에이전트(User-Agent) 설정
    • 헤드리스(Headless) 모드 설정
    • 웹 브라우저의 캐시 사용 여부 설정 등
  2. Firefox Options: Firefox 브라우저를 자동화할 때 사용되는 옵션입니다. Chrome Options와 비슷한 목적으로 사용되며, 다음과 같은 용도로 활용됩니다:
    • 브라우저 창 크기 설정
    • 사용자 에이전트(User-Agent) 설정
    • 헤드리스(Headless) 모드 설정
    • 쿠키 사용 여부 설정 등
  3. Edge Options: Microsoft Edge 브라우저를 자동화할 때 사용되는 옵션입니다. Chrome과 Firefox의 옵션과 비슷하게 사용되며, 웹 브라우저 동작에 영향을 미칩니다.

Selenium options이란?

Selenium을 사용하여 웹 브라우저를 자동화할 때, 웹 드라이버를 초기화할 때 Options를 설정하여 브라우저의 동작을 제어합니다. 각 브라우저에 따라 옵션 이름과 사용법이 조금씩 다를 수 있으므로, 해당 브라우저의 공식 문서를 참조하여 자세한 사용법을 확인하는 것이 좋습니다. Chrome에 대한 options은 아래와 같습니다.

options = webdriver.ChromeOptions()
# options.add_argument("--headless")
options.add_argument("authority=" + "www.coupang.com")
options.add_argument("method=" + "GET")
options.add_argument("accept=" + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
options.add_argument("accept-encoding=" + "gzip, deflate, br")
options.add_argument("user-agent=" + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.104 Whale/3.13.131.36 Safari/537.36")
options.add_argument("sec-ch-ua-platform=" + "macOS")
options.add_argument("cookie=" + "PCID=31489593180081104183684; _fbp=fb.1.1644931520418.1544640325; gd1=Y; X-CP-PT-locale=ko_KR; MARKETID=31489593180081104183684; sid=03ae1c0ed61946c19e760cf1a3d9317d808aca8b; x-coupang-origin-region=KOREA; x-coupang-target-market=KR; x-coupang-accept-language=ko_KR;")

Main Code

쿠팡 데이터 수집에 대한 코드를 어떻게 작성해야하는지 line by line으로 설명 드리겠습니다.


for name, main_url in zip(original_list, url_list) : 
    print("*" * 50 + " " + f"{name}시작하겠습니다." + " " + "*" * 50)
    
    for i in range(1, 6):
        driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)   
        temp_url = main_url + f"{i}"
        driver.get(temp_url)
        time.sleep(10)
        print("*" * 50 + " " + str(i) + "Page start!" + " " + "*" * 50)

        wb = Workbook()
        ws = wb.create_sheet(name)
        wb.remove_sheet(wb["Sheet"])
        ws.append(["상품명", "가격", "배송기한", "상세URL"]) 

        try :
            product = driver.find_element(By.ID, "productList")
            lis = product.find_elements(By.CLASS_NAME, "baby-product")

            for li in lis:
                try : 
                    product = li.find_element(By.CLASS_NAME, "name").text
                    price = li.find_element(By.CLASS_NAME, "price-value").text
                    delivery = li.find_element(By.CLASS_NAME, "delivery").text
                    product_url = li.find_element(By.CLASS_NAME, "baby-product-link").get_attribute("href")
                    ws.append([product, price, delivery, product_url])
                    print("product : ", product)
                    print("price : ", price)
                    print("delivery : ", delivery)
                    print("url : ", product_url)
                except Exception:
                    pass 
            print("*" * 50 + " " + str(i) + "Page end!" + " " + "*" * 50)
            time.sleep(5)
            wb.save(f"/Users/kds/Documents/coupang/{name}_{i}page.xlsx")
            wb.close()
            
            driver.quit()

        except NoSuchElementException :
            print("에러가 발생하여 정상적으로 데이터가 수집되지 않았습니다.")
    
    
print(f"*" * 50 + "모든 데이터 수집을 마쳤습니다. 감사합니다. " + " " + "*" * 50)

쿠팡 데이터 수집 Main code 상세설명

  1. 저는 먼저 쿠팡 데이터 수집을 위해 original_list, url_list를 zip으로 묶어주고, 같이 넘어올 수 있도록 설정하였습니다.
  2. 각각의 인자를 name, main_url로 받아오겠습니다. 여기서 main_url로 설정한 이유는 뒤이어 page number를 붙혀서 temp_url를 만들어주기 위함입니다.
  3. 저는 많은 양의 데이터가 필요한 것이 아니기 때문에 1~5페이지 정도만 연습하였습니다.
  4. driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) 이 코드가 매우 신기하실텐데요. 예전에는 각 크롬 버전에 맞춰서 chromedriver(크롬드라이버)를 설치해주어야 했습니다. 만약, 크롬드라이버의 버전이 맞지 않는 경우, Selenium이 작동하지 않았습니다. 크롬이 버전 업데이트를 생각보다 자주하기 때문에 이는 매우 귀찮은 일이였습니다. 그런데, driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) 코드가 업데이트되면서 이런 버전을 맞춰줄 필요가 없습니다. 매번 알아서 버전을 맞춰주고, 필요한 드라이버를 가져올 수 있도록 업데이트가 되었습니다.
  5. temp_url = main_url + f”{i}” 를 이용하여 각 페이지에 해당하는 url을 만들게 됩니다.
  6. driver.get(temp_url)를 활용하여 url에 driver가 방문하도록 합니다.
  7. 너무 빠르게 작동하면 서버에서 cut(컷!) 당하기 때문에 sleep을 일정량 줍니다.
  8. 받아온 데이터를 workbook()를 이용하여 저장하기 위해 wb를 변수명으로 설정합니다.
  9. worksheet를 설정하고, 기존에 시트는 지우고, 표의 목차를 입력해줍니다.
  10. 페이지를 넘기다 오류가 발생될 경우를 대비하여 try, except를 적용해줍니다.
  11. product = driver.find_element(By.ID, “productList”)를 통해 페이지에 있는 상품 리스트를 한번에 가져옵니다. 한번에 가져와야 서버 리소스를 적게 사용하니 컷 안당합니다.
  12. 가져온 리소스에서 원하는 정보를 찾습니다. 이렇게 하면 서버에서 가져오는 것은 한번이면 됩니다.
  13. 필요한 정보를 클래스명에 입력하고, 변수로 설정합니다.
  14. wb.save(f”/Users/kds/Documents/coupang/{name}_{i}page.xlsx”)로 가져온 값을 페이지별로 저장합니다.
  15. 혹시 중간에 컷 당하면, 이어서 하기 쉽게 각 페이지별로 데이터를 저장하도록 하였습니다.
  16. 한 차례 for문을 돌면, driver와 wb가 새롭게 시작될 수 있도록 종료합니다.

위와 같은 방법으로 크롤링이 진행되며, 코드가 궁금하신 분들은 깃허브를 참고하시면 됩니다.

제가 복사가 되도록 설정을 한다고 했는데, 안될 수도 있으니 깃허브링크 남겨드립니다.

깃허브에 가시면 데이터도 그대로 있으니 필요하신 분들이 가져다 쓰셔도 됩니다. 대신 가져가실때 star 부탁드려요!!

혹시 몰라서 깃허브에 어떻게 올리고 프로젝트가 마무리되면 어떻게 해야하는지도 함께 설명 드리겠습니다.

먼저, 깃에 가셔서 빈 repo를 하나 만듭니다.

git repo first step

1. Owner만 작성하고, repo 이름만 설정한 후 Create repository를 누릅니다.

2. git repo를 복사합니다.

3. 올리고 싶은 폴더 경로에 옵니다.

git init
git add . # 여기 있는 모든 파일을 올리고 싶을 때 
git commit -m "create repo" # commit 메세지를 적음 
git remote add origin https://github.com/daje0601/coupang_crawling.git
git push -u origin master    

4. 이제 프로젝트가 끝났으니 폴더도 지우고, 깃 추적도 지워야겠죠?

# tag를 설정
git tag v1.0 

# tag push 
git push origin --tags

# remove 
git remote remove origin 

# remove check
git remote -v 

5. 이제 폴더도 삭제합니다.

# 현재 위치에서 한 step 위로 올라감 
cd .. 

# 삭제
rm -rf coupang 

이 외에도 다양한 글들이 있으니 참고 부탁드립니다.

감사합니다.

답글 남기기