[육아용품] 쿠팡에서 파는 육아용품 현황 분석

[육아용품] - 쿠팡에서 파는 육아용품 데이터 수집왜 쿠팡에서 육아용품을 분석하는가?쿠팡은 대한민국 이커머스 시장에서 약 37.7%의 점유율을 차지하는 가장 큰 플랫폼으로, 국내 온라인 쇼핑

lifehack-code.tistory.com

 

 

[육아용품] ChatGPT 사용 군집화 시도 실패

[육아용품] - 쿠팡에서 파는 육아용품 현황 분석[육아용품] - 쿠팡에서 파는 육아용품 데이터 수집왜 쿠팡에서 육아용품을 분석하는가?쿠팡은 대한민국 이커머스 시장에서 약 37.7%의 점유율을 차

lifehack-code.tistory.com

 

개요

위의 두 포스팅을 거쳐서 결국 카테고리를 스크래핑 했다. 처음 수집했던 데이터의 링크 필드를 사용해 카테고리를 스크래핑 했다. 스크래핑 도구는 동일하게 playwright로 했다.

 

 

방법

요기! 부분을 카테고리로 선정한다. 페이지에 들어갔을때 '출산/유아동' 이라는 카테고리가 있다면 바로 오른쪽 옆과 그 옆 카테고리를 수집한다. '출산/유아동'이라는 카테고리가 없다면? 제일 마지막 카테고리와 마지막에서 전 카테고리를 수집한다.

 

결론

1065개 링크를 통해 카테고리를 수집했다. 테이블명은 total_products_category로 했고, 필드에 대한 설명과 추가로 수집한 카테고리 데이터에대한 사진은 아래와 같다. 총 1065개의 데이터에 대한 카테고리가 모였다! 

테이블 필드 설명
테이블 필드 설명

 

물품별 수집된 카테고리
물품별 수집된 카테고리

 

 

스크래핑 코드

스크래핑을 위한 전체 코드이다. 패키지로는 Playwright를 사용했다. 코드단락에 대한 설명은 아래의 코드에 주석처리 되어있다. playwright를 활용한 스크래핑의 전체적인 흐름은 아래 포스팅에서 확인 바란다.

 

 

Playwight로 데이터 수집

Selenium vs Playwright 비교웹스크래핑웹스크래핑이란?웹스크래핑은 웹사이트의 데이터를 자동으로 긁어오는 기술로, 네이버나 구글 같은 웹사이트에서 직접 정보를 복사하고 붙여넣기 하는 대신,

eyatto-coding.tistory.com

import asyncio
from playwright.async_api import async_playwright
import pymysql

# MySQL 데이터베이스 연결 설정
conn = pymysql.connect(
    host='',       # 데이터베이스 호스트 주소
    user='',       # 데이터베이스 사용자 이름
    passwd='',     # 데이터베이스 비밀번호
    database='',   # 데이터베이스 이름
    port=,         # 데이터베이스 포트
    charset=''     # 데이터베이스 문자 집합
)

cursor = conn.cursor()  # 데이터베이스 커서 객체 생성

# 데이터 가져오기: total_products 테이블에서 product_id와 link를 가져오는 SQL 쿼리
sql = """
    select product_id, link from total_products
"""

cursor.execute(sql)  # SQL 쿼리 실행
result = cursor.fetchall()  # 모든 결과 가져오기
print(f"db에서 가져온 데이터 갯수: {len(result)}")  # 가져온 데이터의 개수 출력


# SQL SELECT 쿼리 함수 정의
def selectQuery(cursor, sql, where_param=None):
    cursor.execute(sql, where_param)  # SELECT 쿼리 실행
    result = cursor.fetchall()        # 결과 가져오기
    return result                     # 결과 반환

# SQL INSERT 쿼리 함수 정의
def insertQuery(cursor, sql, where_param=None):
    cursor.execute(sql, where_param)  # INSERT 쿼리 실행
    cursor.commit()                   # 커밋하여 데이터베이스에 반영

# 중복 확인 후 삽입 함수 정의
def prev_dup_insert_value(cursor, result, insert_sql, where_param):
    if len(result) > 0:  # 중복 데이터가 있는지 확인
        print("이미 있으므로 저장하지 않습니다.")  # 중복이 있을 경우 메시지 출력
    else:
        insertQuery(cursor, insert_sql, where_param)  # 중복이 없으면 INSERT 쿼리 실행
        print(f"{where_param} inserted successfully.")  # 성공 메시지 출력


# total_products_category 테이블에 데이터 삽입 함수 정의
def insert_product(product_id, sep_name, cat1, cat2):
    try:
        with conn.cursor() as cursor:
            # 동일한 product_id가 있는지 확인하는 SQL 쿼리
            check_sql = "SELECT total_products_idx FROM total_products_category WHERE total_products_idx = %s"
            result = selectQuery(cursor, check_sql, (product_id,))  # 조회하여 결과 가져옴

            # 중복되지 않을 경우 데이터를 삽입하는 SQL 쿼리
            insert_sql = """
                insert into total_products_category(total_products_idx, seperate_name, category1, category2)
                values(%s, %s, %s, %s)
            """
            # 중복 확인 및 데이터 삽입 함수 호출
            prev_dup_insert_value(
                cursor, result, insert_sql, (product_id, sep_name, cat1, cat2)
            )
    except Exception as e:
        print(f"Error occurred: {e}")  # 오류 발생 시 오류 메시지 출력


# 웹 페이지에서 제품 정보를 가져오는 비동기 함수 정의
async def home_get_products():    
    async with async_playwright() as p:  # Playwright 초기화 및 시작
        browser = await p.chromium.launch(headless=False)  # 브라우저 창이 보이도록 설정
        
        # 가져온 각 제품 정보(item) 반복
        for item in result[:10]:  # 예시로 10개의 제품만 가져옴
            print("="*50)
            print(item)

            product_id = item[0]  # item에서 product_id 가져오기
            url = item[1]         # item에서 URL 가져오기
            print(f"url: {url}")

            page = await browser.new_page()  # 새로운 페이지 생성

            try:
                # 지정된 URL로 이동하며, 페이지가 로드될 때까지 60초 대기
                await page.goto(url, timeout=60000)
                
                # 'a.breadcrumb-link' 요소를 모두 찾아 리스트로 저장
                elements = page.locator('a.breadcrumb-link')
                elements_count = await elements.count()  # 요소 개수 가져오기
                elements_text_list = [await elements.nth(i).inner_text() for i in range(elements_count)]
                print(elements_text_list)  # 요소 텍스트 목록 출력

                # 카테고리 추출 로직
                if "출산/유아동" in elements_text_list:
                    target_index = elements_text_list.index("출산/유아동")
                    seperate_name = "출산/유아동"
                    category1 = elements_text_list[target_index + 1]  # 첫 번째 하위 카테고리
                    category2 = elements_text_list[target_index + 2]  # 두 번째 하위 카테고리
                else:
                    target_index = -1
                    seperate_name = ''
                    category1 = elements_text_list[target_index-1]  # 하위 카테고리1 기본값 설정
                    category2 = elements_text_list[target_index]    # 하위 카테고리2 기본값 설정

                print(category1, category2)  # 카테고리 출력

            except Exception as e:
                # 오류 발생 시 기본값으로 할당
                print(f"Error processing URL {url}: {e}")
                seperate_name = "-"
                category1 = "-"
                category2 = "-"

            finally:
                # 데이터 저장 (오류 발생 여부와 상관없이 저장)
                insert_product(product_id, seperate_name, category1, category2)
                await page.close()  # 열린 페이지 닫기

        await browser.close()  # 모든 작업 완료 후 브라우저 종료

# 비동기 함수 실행
asyncio.run(home_get_products())

+ Recent posts