Python을 사용하여 AliExpress 데이터를 스크랩하는 방법

댓글: 0

알리익스프레스와 같은 이커머스 업체에서 정보를 수집하는 것은 제품 정보 수집, 가격 변동 모니터링, 리뷰 수집 등에 매우 유용할 수 있습니다. 이 문서에서는 제품 정보(예: 이름, 가격, 평점 등)를 수집하는 프로세스를 살펴보고 제품 리뷰 스크래핑에 대해서도 살펴봅니다. 또한 제품 URL을 전달하고, 제품 ID를 자동으로 검색하고, 데이터를 CSV 파일로 저장하여 스크래퍼를 동적으로 만드는 방법도 시연합니다.

이 튜토리얼에서는 Playwright를 사용하여 동적 콘텐츠와 리뷰 데이터 가져오기 요청을 렌더링합니다. 또한 스크레이퍼가 윤리적이며 모범 사례를 준수하는지 확인합니다.

요구 사항

시작하기 전에 다음 Python 라이브러리가 설치되어 있는지 확인하세요:

  • Playwright: 브라우저와 상호 작용하고 동적 콘텐츠를 렌더링하는 데 사용됩니다.
  • Requests: AliExpress API를 통해 리뷰를 가져오는 데 사용됩니다.
  • lxml: HTML 콘텐츠 구문 분석에 사용됩니다.
  • 팬더: 데이터를 CSV 파일에 저장하는 데 사용됩니다.

다음 명령을 실행하여 이러한 패키지를 설치할 수 있습니다:


# 설치 Playwright
pip install playwright


# 설치 Requests
pip install requests


# HTML 구문 분석을 위한 lxml 설치
pip install lxml


# 데이터 조작 및 저장을 위한 Pandas 설치
pip install pandas

Playwright를 설치한 후에는 필요한 브라우저 바이너리도 설치해야 합니다:


playwright install

Playwright가 제대로 작동하는 데 필요한 브라우저를 다운로드하고 설정합니다.

1단계. Playwright로 요청 보내기

AliExpress 제품 페이지는 동적이므로 JavaScript를 통해 콘텐츠를 로드합니다. 이를 처리하기 위해 헤드리스 브라우저를 제어하고 동적 콘텐츠와 상호 작용할 수 있는 Python 라이브러리인 Playwright를 사용하겠습니다.

요청을 전송하고 제품 페이지로 이동하는 방법은 다음과 같습니다:


from playwright.async_api import async_playwright

async def get_page_content(url):
    async with async_playwright() as p:
        # 필요한 경우 프록시를 사용하여 브라우저를 실행합니다(프록시를 사용하지 않는 경우 제거 가능).
        browser = await p.firefox.launch(
            headless=False,
            proxy={"server": '', 'username': '', 'password': ''}
        )
        page = await browser.new_page()
        await page.goto(url, timeout=60000)

        # 페이지 콘텐츠 추출
        content = await page.content()
        await browser.close()
        
        return content

# URL 예시
url = 'https://www.aliexpress.com/item/3256805354456256.html'

2단계. 제품 데이터 추출

페이지 콘텐츠가 확보되면 lxml 및 XPath 쿼리를 사용하여 제품 데이터를 추출할 수 있습니다. 제품 제목, 가격, 평점, 리뷰 수, 판매된 상품 수와 같은 세부 정보를 수집합니다.


from lxml.html import fromstring

def extract_product_data(content):
    parser = fromstring(content)
    
    # XPath를 사용하여 제품 세부 정보 추출
    title = parser.xpath('//h1[@data-pl="product-title"]/text()')[0].strip()
    price = parser.xpath('//div[@class="price--current--I3Zeidd product-price-current"]/span/text()')[0].strip()
    rating = ' '.join(parser.xpath('//a[@class="reviewer--rating--xrWWFzx"]/strong/text()')).strip()
    total_reviews = parser.xpath('//a[@class="reviewer--reviews--cx7Zs_V"]/text()')[0].strip()
    sold_count = parser.xpath('//span[@class="reviewer--sold--ytPeoEy"]/text()')[0].strip()

    product_data = {
        'title': title,
        'price': price,
        'rating': rating,
        'total_reviews': total_reviews,
        'sold_count': sold_count
    }

    return product_data


이 코드는 XPath를 사용하여 페이지의 HTML 콘텐츠에서 관련 제품 세부 정보를 추출합니다.

3단계. 제품 리뷰 스크랩

AliExpress에는 제품 리뷰를 가져오기 위한 별도의 API 엔드포인트가 있습니다. URL에서 제품 ID를 동적으로 추출하여 요청을 통해 리뷰를 가져오는 데 사용할 수 있습니다. 이 기능에서:

  1. 제품 URL에서 제품 ID를 동적으로 추출합니다.
  2. 알리익스프레스 리뷰 API를 사용하여 리뷰를 가져옵니다.
  3. 리뷰 텍스트가 추출되어 목록으로 반환됩니다.

import requests

def extract_product_id(url):
    # URL에서 제품 ID 추출
    product_id = url.split('/')[-1].split('.')[0]
    return product_id

def scrape_reviews(product_id, page_num=1, page_size=10):
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'en-IN,en;q=0.9',
        'referer': f'https://www.aliexpress.com/item/{product_id}.html',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
    }

    params = {
        'productId': product_id,
        'lang': 'en_US',
        'country': 'US',
        'page': str(page_num),
        'pageSize': str(page_size),
        'filter': 'all',
        'sort': 'complex_default',
    }

    response = requests.get('https://feedback.aliexpress.com/pc/searchEvaluation.do', params=params, headers=headers)
    reviews = response.json()['data']['evaViewList']

    # 리뷰 텍스트만 추출
    review_texts = [review['buyerFeedback'] for review in reviews]
    
    return review_texts

4단계. 데이터를 CSV 파일로 저장

제품 세부 정보와 리뷰를 스크랩한 후 pandas 라이브러리를 사용하여 이 데이터를 CSV 파일로 저장합니다.


import pandas as pd

def save_to_csv(product_data, reviews, product_id):
    # 제품 세부 정보를 CSV에 저장
    df_product = pd.DataFrame([product_data])
    df_product.to_csv(f'product_{product_id}_data.csv', index=False)

    # 리뷰를 CSV에 저장
    df_reviews = pd.DataFrame({'reviews': reviews})
    df_reviews.to_csv(f'product_{product_id}_reviews.csv', index=False)
    
    print(f"Data saved for product {product_id}.")

제품 세부 정보와 리뷰는 쉽게 식별할 수 있도록 파일 이름에 제품 ID가 포함된 별도의 CSV 파일로 저장됩니다.

5단계. 동적 제품 ID 검색

전체 동적 워크플로 작동 방식은 다음과 같습니다:

  1. 알리익스프레스 제품 URL을 전달합니다.
  2. URL에서 제품 ID를 추출합니다.
  3. 스크레이퍼가 제품 데이터와 리뷰를 가져옵니다.
  4. 데이터는 제품 ID가 포함된 CSV 파일로 저장됩니다.

# URL에서 제품 ID 추출
def extract_product_id(url):
    return url.split('/')[-1].split('.')[0]

최종 완성 코드


from playwright.async_api import async_playwright
from lxml.html import fromstring
import requests
import pandas as pd

# Playwright를 사용하여 페이지 콘텐츠 가져오기
async def get_page_content(url):
    async with async_playwright() as p:
        browser = await p.firefox.launch(
            headless=False,
            proxy={"server": '', 'username': '', 'password': ''}
        )
        page = await browser.new_page()
        await page.goto(url, timeout=60000)
        content = await page.content()
        await browser.close()
        return content

# 제품 데이터 추출
def extract_product_data(content):
    parser = fromstring(content)
    title = parser.xpath('//h1[@data-pl="product-title"]/text()')[0].strip()
    price = parser.xpath('//div[@class="price--current--I3Zeidd product-price-current"]/span/text()')[0].strip()
    rating = ' '.join(parser.xpath('//a[@class="reviewer--rating--xrWWFzx"]/strong/text()')).strip()
    total_reviews = parser.xpath('//a[@class="reviewer--reviews--cx7Zs_V"]/text()')[0].strip()
    sold_count = parser.xpath('//span[@class="reviewer--sold--ytPeoEy"]/text()')[0].strip()

    return {
        'title': title,
        'price': price,
        'rating': rating,
        'total_reviews': total_reviews,
        'sold_count': sold_count
    }

# URL에서 제품 ID 추출
def extract_product_id(url):
    return url.split('/')[-1].split('.')[0]

# 스크랩 리뷰
def scrape_reviews(product_id, page_num=1, page_size=10):
    headers = {
        'accept': 'application/json, text/plain, */*',
        'referer': f'https://www.aliexpress.com/item/{product_id}.html',
        'user-agent': 'Mozilla/5.0'
    }
    params = {
        'productId': product_id,
        'lang': 'en_US',
        'page': str(page_num),
        'pageSize': str(page_size),
    }
    response = requests.get('https://feedback.aliexpress.com/pc/searchEvaluation.do', params=params, headers=headers)
    reviews = response.json()['data']['evaViewList']
    return [review['buyerFeedback'] for review in reviews]

# 제품 데이터 및 리뷰를 CSV에 저장
def save_to_csv(product_data, reviews, product_id):
    pd.DataFrame([product_data]).to_csv(f'product_{product_id}_data.csv', index=False)
    pd.DataFrame({'reviews': reviews}).to_csv(f'product_{product_id}_reviews.csv', index=False)
    print(f'Saved into: product_{product_id}_data.csv')
    print(f'Saved into: product_{product_id}_reviews.csv')

# 주요 기능
async def main(url):
    content = await get_page_content(url)
    product_data = extract_product_data(content)
    product_id = extract_product_id(url)
    reviews = scrape_reviews(product_id)
    save_to_csv(product_data, reviews, product_id)

# 스크레이퍼 실행
import asyncio
url = 'https://www.aliexpress.com/item/3256805354456256.html'
asyncio.run(main(url))

윤리적 고려 사항

데이터를 스크랩할 때는 윤리적 지침을 따르는 것이 중요합니다:

  1. 알리익스프레스의 서비스 약관을 존중하세요: 웹사이트를 스크랩하기 전에 항상 서비스 약관을 확인하세요. 금지 조치를 당하지 않도록 약관을 위반하지 마세요.
  2. 요청을 조절하세요: 단시간에 너무 많은 요청을 보내면 서버에 과부하가 걸릴 수 있습니다. 요청 사이에 지연 시간을 추가하는 것을 고려하세요.
  3. 개인 정보를 피하세요: 적절한 동의 없이 개인 정보를 수집하거나 스크랩하지 마세요.

이 가이드라인을 준수하면 윤리적이고 책임감 있게 스크랩하여 사용자와 AliExpress 시스템 모두의 위험을 최소화하는 데 도움이 됩니다.

댓글:

0 댓글