Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Tags
more
Archives
Today
Total
관리 메뉴

EYaTToCoding

Playwight로 데이터 수집 본문

카테고리 없음

Playwight로 데이터 수집

야토. 2024. 10. 30. 06:14

 

 

Selenium vs Playwright 비교

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

eyatto-coding.tistory.com

 

쿠팡 육아용품 스크래핑

이번 포스팅에서는 Playwright를 이용해 쿠팡에서 육아용품을 스크래핑해보려고 한다. Playwright의 비동기 기능을 활용해서 빠르고 효율적으로 데이터를 수집하는 방법을 설명한다. 그럼 코드의 주요 부분을 단계별로 살펴보자!

 

1. 필요한 모듈 Import하기

우선 이 코드를 작성하기 위해 필요한 라이브러리들을 import 해보자. Playwright와 정규표현식 처리를 위한 모듈들을 가져온다.

import asyncio
from playwright.async_api import async_playwright  # 비동기 Playwright 기능을 가져오기 위해 사용
import re  # 정규표현식 처리를 위해 사용
import pymysql  # MySQL 데이터베이스와 연결하기 위해 사용

 

2. MySQL 데이터베이스 연결

스크래핑한 데이터를 저장하기 위해 MySQL 데이터베이스에 연결하는 부분이다. pymysql 라이브러리를 사용해서 MySQL에 접속하고 데이터를 삽입할 준비를 한다. 여기서 conn 객체는 MySQL 데이터베이스와의 연결을 나타내고, 이후 코드에서 데이터를 삽입할 때 사용한다. 실제로 사용할 때는 적절한 데이터베이스 정보로 바꾸어야 한다.

# MySQL 데이터베이스 연결 설정
conn = pymysql.connect(
    host='',
    user='',
    passwd='',
    database='',
    port=,
    charset=''
)

 

3. 데이터베이스에 상품 정보 삽입 함수

이제 insert_product라는 함수를 정의해서 제품 정보를 MySQL에 삽입한다. 이 함수는 제품 ID를 기준으로 중복된 데이터를 제외하고, 새로운 제품 정보만 데이터베이스에 삽입한다.

# 제품 정보를 데이터베이스에 삽입하는 함수
def insert_product(item_id, product_name, price, review_count, link, rating, rocket_text):
    try:
        with conn.cursor() as cursor:
            # 동일한 제품 ID가 있는지 확인
            check_sql = "SELECT product_id FROM total_products WHERE product_id = %s"
            cursor.execute(check_sql, (item_id,))
            result = cursor.fetchall()

            if len(result) > 0:
                # 이미 존재하는 제품인 경우
                print(f"같은 id({item_id})가 있으므로 저장하지 않습니다.")
            else:
                # 새로운 제품 정보를 삽입
                insert_sql = """
                    INSERT INTO total_products (product_id, product_name, price, review_count, link, rating, rocket)
                    VALUES (%s, %s, %s, %s, %s, %s, %s)
                """
                cursor.execute(insert_sql, (item_id, product_name, price, review_count, link, rating, rocket_text))
                conn.commit()
                print(f"Product {product_name} inserted successfully.")

    except Exception as e:
        print(f"Error occurred: {e}")

 

4. Playwright로 텍스트와 속성 가져오기

다음으로 특정 HTML 요소의 텍스트와 속성을 가져오는 보조 함수를 정의한다. Playwright로 요소를 선택하고, 텍스트나 속성을 반환한다.

# 특정 요소의 텍스트를 가져오는 함수
async def get_element_text(element, locator):
    elem = element.locator(locator)
    if await elem.count() > 0:
        return await elem.inner_text()
    else:
        return ''

# 특정 요소의 속성을 가져오는 함수
async def get_element_attribute(element, locator, attr):
    elem = element.locator(locator)
    if await elem.count() > 0:
        return await elem.get_attribute(attr)
    else:
        return ''

 

5. Playwright로 쿠팡 상품 정보 가져오기

이제 쿠팡에서 실제로 상품 정보를 수집하는 home_get_products 함수를 살펴보자. Playwright의 비동기 기능을 활용해 여러 페이지의 데이터를 수집한다. 쿠팡의 특정 카테고리 URL을 설정하고, Playwright로 새 페이지를 열어 원하는 HTML 요소를 찾는다.

# 쿠팡의 특정 카테고리 페이지에서 제품 정보를 수집하는 함수
async def home_get_products():    
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)  # 브라우저 실행

        # 여러 페이지를 순회하며 데이터 수집
        for i in range(1, 11):
            print("="*50)
            print(f"page: {i}")

            # 쿠팡 카테고리 URL 설정
            url = f"https://www.coupang.com/np/categories/221934?listSize=120&sorter=saleCountDesc&page={i}"
            print(f"url: {url}")

            # 새 페이지 열기
            page = await browser.new_page()
            await page.goto(url, timeout=60000)  # 60초 타임아웃 설정

            # 상품 요소 찾기
            elements = page.locator(".baby-product.renew-badge")
            counts = await elements.count()
            print(f"{counts}개의 요소를 찾았습니다.")

 

6. 페이지에서 제품 정보 수집 및 삽입

이제 각 요소에서 제품명, 가격, 리뷰 수, 링크, 평점, 로켓배송 여부 등의 정보를 추출하고 데이터베이스에 삽입한다. 각 제품 정보를 추출하고 데이터베이스에 삽입하는 역할을 한다. 제품 ID를 통해 중복을 방지하며, 필요한 속성들을 추출해 insert_product 함수에 전달한다.

            for i in range(1, counts+1):
                # 제품명
                name_text = await get_element_text(elements.nth(i), '.name')
                
                # 가격
                price_text = re.sub(r'\D', '', await get_element_text(elements.nth(i), 'strong.price-value'))
                
                # 리뷰 수
                review_text = await get_element_text(elements.nth(i), 'span.rating-total-count')                
                review_count = re.sub(r"\D", "", review_text)
                
                # 링크
                link_text = await get_element_attribute(elements.nth(i), 'a.baby-product-link', 'href')
                full_link = f"https://coupang.com{link_text}"
                
                # 아이템 ID 추출
                item_id_match = re.search(r"itemId=(\d+)", full_link)
                item_id = item_id_match.group(1) if item_id_match else ""
                
                # 평점
                rating_text = await get_element_text(elements.nth(i), 'em.rating')
                
                # 로켓 배송 여부
                rocket_text = await get_element_attribute(elements.nth(i), 'span.badge.rocket img', 'alt')

                # 데이터 삽입 함수 호출
                insert_product(item_id, name_text, price_text, review_count, full_link, rating_text, rocket_text)

 

7. 브라우저와 페이지 닫기

마지막으로 모든 페이지와 브라우저를 닫아 리소스를 정리해준다.

            await page.close()  # 페이지 닫기

        await browser.close()  # 브라우저 닫기
        
        
asyncio.run(home_get_products()) #함수 실행

 

 

이제 Playwright를 통해 쿠팡에서 육아용품을 스크래핑할 수 있다! Playwright는 Selenium에 비해 빠르고 다양한 브라우저 지원이 가능해 동적 웹스크래핑에 매우 유리하다. 육아용품 스크래핑의 이유, 분석과정 등은 아래 포스팅에서 확인할 수 있다.

 

[육아용품] - 쿠팡에서 파는 육아용품 데이터 수집

왜 쿠팡에서 육아용품을 분석하는가?쿠팡은 대한민국 이커머스 시장에서 약 37.7%의 점유율을 차지하는 가장 큰 플랫폼으로, 국내 온라인 쇼핑 산업의 핵심 역할을 하고 있다. 이러한 시장 점유

lifehack-code.tistory.com