Python으로 Etsy 크롤링하기: 검색, 상품, 샵 및 리뷰

최종 업데이트: June 9, 2026
Python으로 Etsy 크롤링하기: 검색, 상품, 샵 및 리뷰

Etsy에는 활성 상품 1억 개, 판매자 560만 명, 그리고 월 4억 5천만 건쯤의 방문이 모여요. 가격, 트렌드, 리뷰, 경쟁사 동향 같은 공개 데이터가 그만큼 쌓여 있다는 뜻이죠. 직접 그러모아 본 분이라면 이게 얼마나 고된 일인지 아실 거예요.

예전에 시장 조사 한답시고 경쟁사 상품을 손으로 정리하다가 주말을 통째로 날린 적이 있어요. 상품 번호가 30번을 넘어가던 무렵, 제가 어쩌다 이 스프레드시트 앞에 앉아 있는지 인생을 되짚어보게 되더라고요. Etsy 데이터는 가격 분석, 제품 개발, 틈새 발굴, 판매자 벤치마킹에 정말 쓸모가 많아요. 단, 규모 있게 실제로 가져올 수 있을 때 얘기죠. 이 글이 노리는 게 바로 그거예요. Python으로 Etsy를 긁는 법을 네 가지 페이지 유형(검색 결과, 상품 페이지, 샵 페이지, 리뷰)으로 나눠 한 번에 다루고, Etsy의 봇 차단 방어에 대한 솔직한 설명, 그리고 코딩을 통째로 건너뛰고 싶은 분을 위한 노코드 대안까지 같이 담았어요.

Python으로 Etsy를 긁는다는 게 무슨 뜻일까요?

웹 스크래핑은 한마디로, 웹페이지를 돌면서 원하는 데이터를 자동으로 뽑아내는 코드를 짜는 거예요. 상품명, 가격, 설명, 이미지, 평점, 리뷰, 샵 정보를 가져와 스프레드시트나 데이터베이스 같은 구조화된 형태로 정리하는 작업이죠.

이런 일에 Python이 가장 많이 쓰여요. 입문자도 쉽게 시작하고, 커뮤니티가 크고, 스크래핑 특화 라이브러리 생태계도 풍부하거든요. 대표적으로 Requests(페이지 요청), BeautifulSoup(HTML 파싱), Selenium·Playwright(브라우저 자동화), pandas(데이터 정리·내보내기)가 있어요. Python은 Stack Overflow 연례 개발자 설문에서 꾸준히 인기 상위 3개 언어에 들고, PyPI에서도 스크래핑 라이브러리 다운로드가 상위권이에요.

Etsy를 긁을 땐 브라우저로 전달되는 HTML(때로는 숨은 JSON)에서 데이터를 가져와요. 뽑을 수 있는 데이터 유형은 이래요.

  • 상품명, 가격, 설명, 이미지, 옵션
  • 판매자/샵 정보(이름, 판매 수, 위치, 평점)
  • 평점과 전체 리뷰 텍스트
  • 검색 결과 목록, 카테고리, 트렌드 신호

왜 Etsy를 긁을까요? ROI를 만드는 실제 활용 사례

Etsy 스크래핑은 단순한 기술 연습이 아니라 경쟁 우위가 돼요. 판매자든, 제품 관리자든, 데이터 분석가든, 구조화된 Etsy 데이터를 바로 쓸 수 있으면 수익에 곧장 영향을 줄 수 있죠.

etsy_stats_4f1f4d51c3.png

활용 사례무엇을 크롤링하나요누가 혜택을 보나요비즈니스 효과
경쟁 가격 분석검색 결과 + 상품 가격이커머스 운영, 판매자동적 가격 책정은 평균적으로 수익을 5~22% 높일 수 있음
틈새시장 및 트렌드 발굴검색 결과, 인기 상품 목록창업자, 분석가유망한 틈새를 조기에 포착 가능(예: "preppy pajamas"의 검색량이 +1,112% 증가)
제품 개발 및 개선리뷰, 상품 상세제품팀한 주방용품 브랜드는 리뷰 감성 데이터를 활용해 60일 만에 #1 베스트셀러를 되찾음
SEO 및 키워드 조사검색 결과, 상품 제목/태그마케팅팀수요는 높고 경쟁은 낮은 키워드 식별
판매자 벤치마킹샵 페이지, 판매 수세일즈팀, 분석가구매한 리드 목록보다 훨씬 저렴한 건당 $0.01~0.10 수준으로 검증된 리드 리스트 구축
재고 및 품절 모니터링상품 재고 상태이커머스 운영경쟁사 재고 변동에 더 빠르게 대응

이 활용 사례들은 저마다 다른 Etsy 페이지 유형의 데이터를 써요. 그래서 이 튜토리얼에서 네 가지를 다 다루는 거예요.

시간 절약: 수작업 vs 자동화

  • 수동 Etsy 조사: 상품당 3045분(100개면 5075시간)
  • 자동 크롤링: 100개 목록을 2~5분 안에 처리
  • AI 기반 스크래핑은 30~40% 더 빠르고 정확도는 최대 99.5%

Etsy API vs. 웹 스크래핑: 무엇을 골라야 할까요?

코드 한 줄 쓰기 전에 먼저 던져볼 질문이 있어요. Etsy 공식 API를 쓸까요, 아니면 사이트를 직접 긁을까요? 포럼에서도 자주 보이는 고민인데, 답은 필요한 데이터가 뭐냐에 달려 있어요.

Etsy API가 되는 것과 안 되는 것

Etsy는 OAuth 2.0 인증을 쓰는 API v3를 제공해요. 본인 샵 데이터, 즉 상품 목록, 주문, 영수증에 접근할 땐 유용하죠. 하지만 한계도 뚜렷해요.

  • 경쟁사 데이터: API는 대부분 본인 샵으로 제한돼요. 다른 판매자의 가격, 판매량, 상품 목록은 못 가져와요.
  • 리뷰: 전체 리뷰 텍스트를 대량으로 받아올 강력한 엔드포인트가 없어요.
  • 요청 제한: 기본값이 초당 10회, 하루 10,000회예요. offset 상한은 12,000개 레코드고요.
  • AI/ML 사용: 앱 검토에서 명시적으로 거부돼요.
  • 문서화: 커뮤니티 불만이 많아요. 예시는 부족하고, 폐기된 엔드포인트도 있고, 지원도 느려요.

웹 스크래핑이 더 나은 경우

경쟁사 인텔리전스, 리뷰 감성 분석, 샵 간 비교, 또는 API가 안 열어주는 데이터가 필요하다면 답은 스크래핑이에요. 대신 Etsy의 봇 차단 방어를 상대해야 하고(아래에서 자세히), 환경도 직접 꾸려야 해요.

비교표: API vs. 스크래핑 vs. 노코드

기준Etsy 공식 APIPython 웹 스크래핑Thunderbit (노코드)
상품 가격 접근✅ (일부 필드만)✅ 전체 HTML/JSON-LD✅ AI가 보이는 필드를 모두 추출
리뷰 데이터❌ 대량 제공 안 됨✅ 리뷰 엔드포인트/HTML 통해 가능✅ 하위 페이지 스크래핑
경쟁사 샵 데이터❌ 본인 샵만 가능✅ 공개 샵이면 모두 가능✅ 공개 샵이면 모두 가능
인증 필요 여부✅ OAuth 2.0⚠️ 로그인 데이터는 쿠키 필요⚠️ 로그인은 브라우저 스크래핑으로 처리
봇 차단 위험없음높음(DataDome)처리됨(브라우저 네이티브)
설정 시간중간(API 키, OAuth)높음(코드 + 프록시)약 2분

경쟁사 데이터, 리뷰, 샵 간 분석이 필요하면 API만으로는 부족해요. 솔직한 현실이에요.

코드 쓰기 전에 Python 스크래핑 방식부터 고르세요

Reddit과 Stack Overflow에서 정말 자주 나오는 질문이 있어요. "Requests + BeautifulSoup이냐, Selenium이냐, 프록시 API냐, 아니면 아예 다른 거냐?" 답은 기술 수준, 예산, 사용 사례에 따라 갈려요.

방식가장 적합한 경우학습 난이도JS 처리 가능?봇 차단 대응비용
Requests + BeautifulSoup완전한 제어를 원하는 개발자중간수동 처리(헤더, 프록시)무료 + 프록시 비용
Selenium / PlaywrightJS가 많은 페이지, 로그인 흐름높음일부만 대응(브라우저 지문)무료 + 프록시 비용
프록시 API 서비스대규모 + 봇 차단 우회중간✅(API 통해)✅ 내장월 $49+
Thunderbit (노코드)비개발자, 빠른 추출매우 낮음✅(브라우저 네이티브)✅(브라우저 세션)무료 플랜 제공

완전한 제어가 필요하고 Python이 손에 익었다면 Requests + BeautifulSoup이 좋아요. JS 렌더링이나 로그인 흐름이 필요하면 Selenium을 쓰고요. 대규모로 봇 차단을 우회해야 하면 프록시 서비스를 고려하세요. 그리고 코드 작성이나 유지보수 없이 Etsy 데이터만 얻고 싶다면 Thunderbit도 충분히 볼 만해요. 이 부분은 뒤에서 더 풀게요.

Etsy는 어떻게 막아낼까요: DataDome 봇 차단 방어 이해하기

대부분의 스크래핑 가이드는 "프록시만 쓰면 된다"고 하고 넘어가요. Etsy에선 그걸로 어림없어요. Etsy는 웹에서 가장 공격적인 봇 차단 시스템 중 하나인 DataDome을 써요. DataDome 자체 사례 연구에서도 Etsy를 성공 사례로 들면서, 예전엔 스크래퍼가 Etsy 컴퓨팅 비용의 약 1%를 잡아먹었다고 밝혀요.

etsy_antibot_5431142c9c.png

DataDome은 뭐고 어떻게 작동하나요?

DataDome은 IP 주소만 보는 게 아니에요. 여러 겹의 탐지 스택을 돌려요.

  • TLS 지문 인식(JA3): Python requests 라이브러리는 DataDome이 즉시 식별하는 고유 TLS 서명을 가져요.
  • HTTP 헤더/프로토콜 검사: 완전하고 일관된 브라우저 헤더를 따져요. 누락되거나 순서가 어긋난 헤더는 곧 경고 신호죠.
  • JavaScript 지문 인식(Picasso 프로토콜): 브라우저에서 JS 챌린지를 돌려 진짜 사용자인지 검증해요.
  • 행동 기반 ML: 요청당 신호 35개 이상을 분석하고, 사이트별 모델을 85,000개 넘게 써요.
  • IP 평판 점수화: 데이터센터 IP는 즉시 표시돼요.
  • 쿠키 검증: datadome 쿠키가 있고 유효해야 해요.

차단됐는지 확인하는 신호와 점검법

가장 흔한 함정 하나는 200 OK를 받고도 정작 원하던 데이터가 아니라 CAPTCHA 페이지가 떨어지는 경우예요. 다른 신호도 있어요.

  • 403 Forbidden 오류
  • 리다이렉트 루프
  • 응답 본문에 dd JavaScript 객체나 슬라이더 CAPTCHA HTML이 섞임

상태 코드만 믿지 말고 항상 응답 본문까지 확인하세요. 간단한 점검 예시는 이래요.

if "captcha" in resp.text.lower() or "datadome" in resp.text.lower():
    print("차단되었습니다! 데이터 대신 CAPTCHA 페이지를 받았습니다.")

탐지를 줄이는 헤더와 쿠키

차단을 100% 피한다고 장담할 순 없지만, 현실적인 헤더와 쿠키 관리는 확실히 도움이 돼요.

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/133.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Ch-Ua": '"Chromium";v="133", "Not-A.Brand";v="99", "Google Chrome";v="133"',
    "Sec-Ch-Ua-Mobile": "?0",
    "Sec-Ch-Ua-Platform": '"Windows"',
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Upgrade-Insecure-Requests": "1",
})

그리고 이런 것도 챙기세요.

  • requests.Session()으로 요청 간 쿠키를 유지하세요.
  • 요청 사이에 랜덤 지연(2~7초)을 넣으세요.
  • 리퍼러 체인을 흉내 내세요. 홈페이지 먼저, 그다음 검색 페이지, 마지막에 상품 페이지 순서로요.
  • 대규모 작업이면 주거용 프록시 로테이션이 필수예요. 데이터센터 IP는 거의 즉시 표시돼요.

이 방법들은 탐지를 줄여줄 뿐 없애주진 못해요. 대량 스크래핑이라면 결국 프록시 서비스나 브라우저 기반 접근이 필요해질 가능성이 커요.

Etsy를 긁기 위한 Python 환경 설정

시작하기 전에 정리할게요.

  • 난이도: 중급
  • 소요 시간: 약 30~60분(설정 + 첫 크롤링)
  • 준비물: Python 3.8+, pip, 코드 에디터, Chrome 브라우저(DevTools 확인용)

의존성 설치

프로젝트 폴더를 만들고 가상 환경을 잡은 뒤 필요한 라이브러리를 깔아요.

mkdir etsy-scraper && cd etsy-scraper
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

pip install requests beautifulsoup4 lxml pandas
  • requests — 웹페이지 요청
  • beautifulsoup4 — HTML 파싱
  • lxml — 더 빠른 HTML 파서(선택이지만 권장)
  • pandas — 데이터를 CSV/Excel로 정리·내보내기

나중에 로그인이나 JS가 많은 페이지 때문에 브라우저 자동화가 필요하면 이것도 깔아요.

pip install selenium

코드 쓰기 전에 Etsy 페이지 구조를 파악하세요

시간을 크게 아껴주는 팁이 있어요. Etsy는 대부분의 페이지에서 <script type="application/ld+json"> 안에 구조화된 상품 데이터를 넣어둬요. 이 JSON-LD에는 상품명, 가격, 평점, 이미지가 이미 정리돼 있어서, 필드마다 불안정한 CSS 선택자와 씨름할 필요가 없죠.

아무 Etsy 상품 페이지나 열고 우클릭해 "페이지 소스 보기"를 누른 뒤 application/ld+json을 찾아보세요. 필요한 데이터 대부분을 담은 @type: Product 블록이 보일 거예요. 검색 결과 페이지엔 @type: ItemList가 있고요.

CSS 선택자는 배송 정보나 리뷰 텍스트처럼 JSON-LD에 없는 데이터를 가져올 때 쓰는 대체 수단이에요. 첫 번째 선택지는 어디까지나 JSON-LD여야 해요.

1단계: Python으로 Etsy 검색 결과 긁기

검색 결과는 대부분의 Etsy 스크래핑 프로젝트가 출발하는 지점이에요. 틈새를 모니터링하든, 경쟁 가격을 추적하든, 상품 데이터베이스를 만들든 마찬가지죠.

검색 URL 만들기

Etsy 검색 URL은 이런 형식을 따라요.

https://www.etsy.com/search?q={keyword}&ref=pagination&page={page_number}

여러 단어 검색어는 공백을 URL 인코딩하세요(예: handmade+jewelry 또는 handmade%20jewelry). ref=pagination 파라미터를 붙이면 요청이 더 실제 브라우저 이동처럼 보여요.

추가로 쓸 만한 파라미터는 order(most_relevant, price_asc, price_desc, date_desc), min_price, max_price, ship_to, free_shipping=true예요. 한 페이지당 48개 항목을 반환해요.

요청 보내고 HTML 파싱하기

import requests
from bs4 import BeautifulSoup
import json
import time
import random

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
}

def scrape_etsy_search(query, max_pages=3):
    all_products = []
    for page in range(1, max_pages + 1):
        url = f"https://www.etsy.com/search?q={query}&ref=pagination&page={page}"
        resp = requests.get(url, headers=headers, timeout=30)
        if "captcha" in resp.text.lower():
            print(f"{page}페이지에서 차단되었습니다. 지연 시간이나 프록시를 추가해 보세요.")
            break
        soup = BeautifulSoup(resp.text, "lxml")
        for script in soup.find_all("script", type="application/ld+json"):
            data = json.loads(script.string)
            if data.get("@type") == "ItemList":
                for item in data.get("itemListElement", []):
                    all_products.append({
                        "name": item.get("name"),
                        "url": item.get("url"),
                        "image": item.get("image"),
                        "price": item.get("offers", {}).get("price"),
                        "currency": item.get("offers", {}).get("priceCurrency"),
                        "position": item.get("position"),
                    })
        time.sleep(random.uniform(2, 5))
    return all_products

JSON-LD에서 상품 목록 데이터 뽑기

itemListElement 배열엔 상품마다 이름, URL, 이미지, 가격, 통화가 들어 있어요. 별점이나 결과 수처럼 JSON-LD에 늘 있지는 않은 정보가 더 필요하면 CSS 선택자로 보완하세요.

  • 목록 카드: .v2-listing-card
  • 제목: h3.v2-listing-card__title
  • 가격: span.currency-value
  • 링크: a.listing-link(href)

페이지네이션 처리하기

페이지를 돌면서 요청 사이에 랜덤 지연을 넣으세요. Etsy는 보통 쿼리에 따라 20~250페이지쯤 반환해요.

results = scrape_etsy_search("handmade+jewelry", max_pages=5)
print(f"{len(results)}개의 상품을 크롤링했습니다.")

5페이지를 긁는 데 제 테스트에선 약 20초가 걸렸어요. 손으로 복사-붙여넣기 하면 30분 넘게 걸릴 일이니, 차이가 어마어마하죠.

2단계: Python으로 Etsy 상품 페이지 긁기

검색 결과에서 상품 URL 목록을 얻었으면, 다음은 상품 페이지마다 들어가 상세 데이터를 가져오는 거예요.

상품 페이지 가져오기

def scrape_etsy_product(url):
    resp = requests.get(url, headers=headers, timeout=30)
    soup = BeautifulSoup(resp.text, "lxml")
    for script in soup.find_all("script", type="application/ld+json"):
        data = json.loads(script.string)
        if data.get("@type") == "Product":
            offers = data.get("offers", {})
            price = offers.get("price") or offers.get("lowPrice")
            rating_data = data.get("aggregateRating", {})
            return {
                "name": data.get("name"),
                "description": data.get("description", "")[:500],
                "brand": data.get("brand", {}).get("name") if isinstance(data.get("brand"), dict) else data.get("brand"),
                "category": data.get("category"),
                "price": price,
                "currency": offers.get("priceCurrency"),
                "availability": offers.get("availability"),
                "rating": rating_data.get("ratingValue"),
                "review_count": rating_data.get("reviewCount"),
                "images": data.get("image", []),
                "sku": data.get("sku"),
                "material": data.get("material"),
            }
    return None

가격 변형 처리하기

상품 일부는 offers.price 하나만 가져요. 반면 크기나 색상 옵션이 있는 상품은 offers.lowPriceoffers.highPrice를 써요. 위 코드는 price가 없으면 lowPrice로 넘어가게 해서 두 경우를 다 잡아요.

CSS 선택자로 추가 필드 파싱하기

배송 정보, 옵션, 판매자 세부 정보처럼 JSON-LD에 없는 데이터는 CSS 선택자가 필요해요.

  • 제목: h1[data-buy-box-listing-title]
  • 옵션: select[data-selector-id] 또는 div[data-option-set]
  • 배송: 배송 섹션 근처의 div.wt-text-caption

트레이드오프는 이래요. JSON-LD는 더 깔끔하고 레이아웃 변경에도 훨씬 잘 버텨요. CSS 선택자는 더 취약하지만 더 많은 필드를 다룰 수 있죠.

3단계: Python으로 Etsy 샵 페이지 긁기

이 부분은 경쟁 가이드가 자주 건너뛰는 영역인데, 세일즈팀과 경쟁 분석가한테는 어쩌면 가장 값진 파트예요.

샵 URL 만들고 페이지 가져오기

def scrape_etsy_shop(shop_name):
    url = f"https://www.etsy.com/shop/{shop_name}"
    resp = requests.get(url, headers=headers, timeout=30)
    soup = BeautifulSoup(resp.text, "lxml")

    # HTML에서 샵 메타데이터 추출(JSON-LD에는 없음)
    sales_el = soup.select_one("div.shop-sales-reviews a")
    rating_el = soup.find("input", {"name": "initial-rating"})
    location_el = soup.select_one("div.shop-location")

    shop_data = {
        "name": shop_name,
        "sales": sales_el.text.strip() if sales_el else None,
        "rating": rating_el["value"] if rating_el else None,
        "location": location_el.text.strip() if location_el else None,
    }

    # JSON-LD에서 상품 목록 추출
    listings = []
    for script in soup.find_all("script", type="application/ld+json"):
        data = json.loads(script.string)
        if data.get("@type") == "ItemList":
            for item in data.get("itemListElement", []):
                listings.append({
                    "name": item.get("name"),
                    "url": item.get("url"),
                    "price": item.get("offers", {}).get("price"),
                })
    shop_data["listings"] = listings
    return shop_data

샵 페이지에서 뽑을 수 있는 것

샵 페이지의 JSON-LD는 @type: ItemList예요. 상품 목록은 담겨 있지만, 판매 수나 위치, 평점 같은 샵 수준 메타데이터는 빠져 있어요. 그 부분은 CSS 선택자가 필요하죠.

데이터 포인트선택자비고
샵 이름h1 또는 메타 제목보통 페이지 제목에 있음
총 판매 수div.shop-sales-reviews a"12,345 sales" 같은 텍스트
별점input[name="initial-rating"]의 value숫자 1~5
위치div.shop-location도시, 국가
가입 시점div.shop-info날짜 텍스트

샵 데이터는 리드 리스트 구축, 경쟁사 벤치마킹, 특정 틈새의 상위 판매자 찾기에 특히 쓸모가 있어요.

4단계: Python으로 Etsy 리뷰 긁기

리뷰는 Etsy에서 가장 값지면서도 가장 까다로운 데이터예요. 전체 리뷰 텍스트, 평점, 날짜는 초기 페이지 HTML에 없고 내부 API 엔드포인트로 로드되거든요.

방법 1: Etsy 내부 리뷰 API 엔드포인트 찾기

Chrome에서 상품 페이지를 열고 DevTools(F12)를 켠 다음 Network 탭으로 가서 리뷰 섹션까지 내려가 보세요. 다음과 비슷한 POST 요청이 보일 거예요.

https://www.etsy.com/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews

이 엔드포인트는 리뷰 카드가 담긴 HTML 조각을 돌려줘요. 쓰려면 이게 필요해요.

  • listing_id — 상품 URL에서 가져오는 숫자 ID
  • shop_id — 정규식으로 상품 페이지 HTML에서 추출
  • csrf_nonce — 페이지의 <meta> 태그에서 추출

ID와 CSRF 토큰 추출하기

import re

def get_review_params(product_url):
    resp = requests.get(product_url, headers=headers)
    html = resp.text
    listing_id = product_url.split("/")[-1].split("?")[0]
    shop_id_match = re.search(r'"shopId"\s*:\s*(\d+)', html)
    shop_id = shop_id_match.group(1) if shop_id_match else None
    soup = BeautifulSoup(html, "lxml")
    csrf_meta = soup.find("meta", {"name": "csrf_nonce"})
    csrf = csrf_meta["content"] if csrf_meta else None
    return listing_id, shop_id, csrf

페이지네이션으로 리뷰 긁기

def scrape_reviews(listing_id, shop_id, csrf, max_pages=5):
    session = requests.Session()
    session.headers.update(headers)
    all_reviews = []
    for page in range(1, max_pages + 1):
        payload = {
            "specs": {
                "deep_dive_reviews": {
                    "module_path": "neu/specs/deep_dive_reviews",
                    "listing_id": listing_id,
                    "shop_id": shop_id,
                    "page": page,
                }
            }
        }
        resp = session.post(
            "https://www.etsy.com/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews",
            json=payload,
            headers={"x-csrf-token": csrf, "Content-Type": "application/json"},
        )
        data = resp.json()
        html_fragment = data.get("output", {}).get("deep_dive_reviews", "")
        review_soup = BeautifulSoup(html_fragment, "lxml")
        for card in review_soup.select("div.review-card"):
            rating_el = card.find("input", {"name": "rating"})
            text_el = card.select_one("div.wt-text-body")
            user_el = card.select_one("a[data-review-username]")
            date_el = card.select_one("p.wt-text-body-small")
            all_reviews.append({
                "rating": rating_el["value"] if rating_el else None,
                "text": text_el.text.strip() if text_el else None,
                "reviewer": user_el.text.strip() if user_el else None,
                "date": date_el.text.strip() if date_el else None,
            })
        time.sleep(random.uniform(2, 5))
    return all_reviews

방법 2: HTML에서 리뷰 파싱하기(대체 방법)

API 방식이 실패하면(예: CSRF 토큰 문제) 상품 페이지 HTML에서 첫 리뷰 묶음을 직접 파싱할 수 있어요. 한계는 정적 HTML에 초기 리뷰 일부만 있다는 점이에요. 더 많이 가져오려면 API나 Selenium 같은 브라우저 자동화 도구가 필요해요.

로그인 필요한 데이터 다루기: 내 Etsy 샵 긁기

이건 다른 튜토리얼이 거의 안 다루는데 실전에선 꽤 자주 필요해요. 특히 Etsy 판매자가 자기 주문, 매출, 통계를 뽑고 싶을 때요.

문제는 requests만으로는 Etsy 대시보드에 못 들어간다는 거예요. 로그인 세션 쿠키가 없으니까요.

옵션 1: Selenium으로 수동 로그인 후 쿠키 캡처

Selenium으로 브라우저를 띄워 수동 로그인하고(또는 로그인 자동화 후) 인증된 상태로 계속 긁을 수 있어요.

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.etsy.com/signin")
# 브라우저 창에서 수동으로 로그인한 다음:
input("로그인 후 Enter를 누르세요...")

cookies = driver.get_cookies()
# 이제 driver.get()으로 대시보드 페이지로 이동하면서 크롤링

Selenium 세션에서 쿠키를 저장해 뒀다가 첫 로그인 이후 requests.Session()과 함께 재사용하면 더 빠르고 가벼운 크롤링도 돼요.

옵션 2: 브라우저 쿠키를 내보내 Requests에 쓰기

브라우저 확장(예: "EditThisCookie")으로 지금 Etsy 세션 쿠키를 내보낸 뒤 Requests 세션에 넣을 수 있어요.

import requests

session = requests.Session()
# 브라우저에서 내보낸 쿠키 추가
session.cookies.set("uaid", "YOUR_UAID_VALUE", domain=".etsy.com")
session.cookies.set("user_prefs", "YOUR_USER_PREFS_VALUE", domain=".etsy.com")
# ... 필요한 다른 세션 쿠키도 추가

resp = session.get("https://www.etsy.com/your/orders", headers=headers)

쉬운 길: Thunderbit의 브라우저 스크래핑 모드

Thunderbit는 Chrome 브라우저 안에서 돌아가니 지금 Etsy 세션을 그대로 가져다 써요. 인증 코드도, 쿠키 내보내기도 필요 없죠. 그냥 Etsy 대시보드로 가서 바로 긁으면 돼요. 주문, 매출, 통계, 그 밖의 판매자 전용 데이터를 스크립트 없이 뽑을 때 정말 편해요.

AI로 Etsy 대시보드 크롤링하기

긁은 Etsy 데이터 내보내고 활용하기

CSV 또는 JSON으로 저장하기

import pandas as pd

df = pd.DataFrame(results)
df.to_csv("etsy_products.csv", index=False, encoding="utf-8")
df.to_json("etsy_products.json", orient="records", indent=2)

권장 사항: 파일명에 타임스탬프를 넣고, UTF-8 인코딩을 쓰고, 상품명에 섞인 특수문자는 잘 처리하세요(Etsy 판매자는 이모지와 악센트 문자를 정말 좋아하거든요).

Google Sheets, Airtable, Notion으로 내보내기

Python 사용자라면 gspread(Google Sheets)나 Airtable API 같은 라이브러리로 데이터를 프로그래밍 방식으로 보낼 수 있어요. 단, Thunderbit를 쓰면 Google Sheets, Excel, Airtable, Notion 내보내기가 전부 무료이고 원클릭이에요. API 키도, OAuth 설정도 필요 없죠.

코딩 없이 Etsy 긁는 법: Thunderbit 노코드 대안

누구나 Python 스크립트를 짜고, 프록시 설정을 손보고, 새벽 2시에 CSS 선택자를 디버깅하고 싶은 건 아니에요. 그런 분이라면, Thunderbit로 Etsy 데이터를 가져오는 법을 알려드릴게요.

Thunderbit Chrome 확장 프로그램 설치하기

Chrome 웹 스토어에서 Thunderbit을 설치하세요. 무료 계정을 만들면 무료 플랜으로 월 6페이지를 쓸 수 있고, 내보내기도 전부 무료예요.

어떤 Etsy 페이지든 AI 추천 필드 쓰기

Etsy 검색, 상품, 샵 페이지로 이동하세요. Thunderbit 사이드바에서 **"AI Suggest Fields"**를 누르면 AI가 페이지를 훑어 상품명, 가격, 평점, 이미지, 샵 이름, 태그, 배송 정보 같은 열을 추천해요. 필요에 맞게 열을 조정하거나 더하면 돼요.

스크랩하고 내보내기 누르기

**"Scrape"**를 누르면 현재 페이지 데이터를 가져와요. 여러 페이지 결과라면 Thunderbit의 페이지네이션 스크래핑을 쓰세요. 상품 URL 목록을 상품 페이지마다의 상세 정보(설명, 리뷰, 배송 정보)로 살찌우고 싶다면 하위 페이지 스크래핑을 쓰면 돼요. Thunderbit이 링크마다 들어가 추가 데이터를 알아서 가져와요.

Excel, Google Sheets, Airtable, Notion으로 전부 무료 내보내기가 돼요.

Etsy 스크래핑에서 Thunderbit가 Python보다 유리한 경우

  • 프록시 설정이나 봇 차단 코드가 필요 없어요. Thunderbit은 진짜 Chrome 브라우저에서 돌아가니 세션을 그대로 이어받고, DataDome엔 일반 사용자처럼 보여요.
  • AI가 레이아웃 변화에 자동으로 적응해요. Etsy가 프런트를 바꿔도 깨진 선택자를 고칠 일이 없죠.
  • 일회성 리서치, 경쟁 분석, 비기술 팀원에게 특히 좋아요. 데이터셋만 빠르게 필요하다면 Python 환경 자체가 필요 없으니까요.
  • 하위 페이지 스크래핑을 쓰면 중첩 루프를 짜지 않고도 상품 URL 목록에 상세 데이터를 얹을 수 있어요.

사용법은 Thunderbit 유튜브 채널에서도 볼 수 있어요.

Python vs. Thunderbit: 6개월 비용 비교

항목Python 직접 구축Thunderbit
설정 시간8~20시간5분 이내
6개월 비용(인건비, 프록시 포함)$2,720~9,450$90~228
월간 유지보수4~10시간 이상(선택자 업데이트가 오버헤드의 80% 이상)0~1시간
봇 차단 대응일반 비용의 85배 수준 주거용 프록시 필요브라우저 기반, DataDome를 네이티브로 우회
데이터 품질높음(노력 필요)높음(AI 기반)

Python이 틀린 선택이라는 말은 아니에요. 완전한 제어, 맞춤 로직, 더 큰 파이프라인 통합이 필요하면 코드는 여전히 강력해요. 단, 대부분의 비즈니스 사용자는 그냥 Etsy 데이터만 있으면 되니까, ROI로 따지면 노코드 도구가 더 유리하죠.

Etsy 긁을 때 법적·윤리적 팁

스크래핑 글마다 합법성 질문이 따라붙으니, 짧게 정리해 드려요.

  • Etsy 이용약관은 자동 접근을 명시적으로 금지해요. 다만 Etsy는 소송보다 기술적 차단(DataDome)에 더 기대고 있고, 스크래퍼를 직접 겨냥한 Etsy 전용 소송은 알려진 바 없어요.
  • 공개 데이터만 긁으세요. 인증을 우회하거나 본인 것이 아닌 비공개 판매자 대시보드에 접근하지 마세요.
  • 합리적인 요청 속도를 지키세요. 요청 사이 2~7초 지연을 두고, Etsy 서버를 과하게 두드리지 마세요.
  • robots.txt를 존중하세요. Etsy는 검색 페이지는 열어두지만 일부 경로는 막아요.
  • 개인정보보호법(PIPA)이나 GDPR 같은 규제에 맞춰 개인 데이터를 책임감 있게 다루세요.
  • 상업적 규모의 크롤링 프로젝트라면 법률 자문을 받으세요.

배경이 더 필요하면 웹 스크래핑의 법적 쟁점 글도 참고하세요. 공개 데이터 스크래핑이 인정된 Meta v. Bright Data(2024) 사례도 담겨 있어요.

마무리: 핵심 요약

오늘 꽤 많은 내용을 다뤘어요. 꼭 챙겨가셨으면 하는 핵심은 이거예요.

  • Etsy의 JSON-LD 구조화 데이터 덕분에 대부분의 필드는 원시 HTML 파싱보다 훨씬 깔끔하게 뽑을 수 있어요.
  • DataDome은 진짜 장벽이에요. Python으로 대규모 크롤링을 하려면 올바른 헤더, 지연, 쿠키 관리, 주거용 프록시가 필요해요.
  • Etsy API는 제한적이에요. 리뷰, 경쟁사 샵, 판매자 간 분석이 필요하면 실용적인 길은 스크래핑이에요.
  • Thunderbit은 노코드 대안으로, 봇 차단과 인증을 네이티브로 처리해요. 스크립트를 유지보수하고 싶지 않다면 한 번 써볼 만해요.
  • 항상 책임감 있게 긁고 Etsy 약관을 존중하세요.

코드 없이 시작하고 싶다면 Thunderbit을 무료로 써보세요. 아니면 이 튜토리얼의 Python 코드로 자기만의 맞춤 스크래퍼를 만들어 보세요. 그리고 금요일 오후에 선택자가 깨지는 일만은 없길 바라요.

더 많은 스크래핑 가이드는 Etsy 스크래퍼 가이드최고의 AI 웹 스크래퍼 정리 글에서 확인하세요.

Thunderbit으로 더 빠르게 Etsy 데이터를 크롤링해 보세요 Get Started Free

자주 묻는 질문

1. Python으로 Etsy를 긁는 건 합법인가요?

공개된 데이터를 긁는 건 최근 판례(예: Meta v. Bright Data, hiQ v. LinkedIn)상 대체로 허용되는 편이에요. 단, Etsy 이용약관은 자동 접근을 금지하니, 긁기 전에 항상 ToS와 robots.txt를 확인하세요. 대규모이거나 상업적 용도라면 법률 자문을 받는 게 좋아요.

2. 차단되지 않고 Etsy를 긁을 수 있나요?

Etsy는 아주 강력한 봇 차단 시스템 DataDome을 써요. 현실적인 헤더, 요청 지연, 쿠키 유지, 주거용 프록시 로테이션이 차단을 줄이는 데 도움이 돼요. Thunderbit의 브라우저 네이티브 방식은 진짜 Chrome 세션 안에서 동작하니 대부분의 탐지를 피해요.

3. 스크래핑 대신 쓸 수 있는 Etsy API가 있나요?

네. Etsy는 API v3를 제공해요. 단, 대부분 본인 샵 데이터로 제한되고, 강력한 리뷰 접근 기능은 없어요. 경쟁 인텔리전스와 샵 간 분석은 대부분 스크래핑이 필요해요.

4. Etsy를 긁으려면 어떤 Python 라이브러리가 필요한가요?

최소한 requests, beautifulsoup4, pandas(내보내기용), json(내장)이면 돼요. JS가 많거나 로그인 필요한 페이지라면 selenium을 더하세요. HTML 파싱이 더 빨라야 하면 lxml을 쓰고요.

5. Etsy 리뷰만 따로 어떻게 긁나요?

Etsy 리뷰는 내부 API 엔드포인트(/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews)로 로드돼요. 상품 페이지에서 listing ID, shop ID, CSRF 토큰을 뽑은 뒤, 페이지네이션과 함께 엔드포인트에 POST 요청을 보내야 해요. 대체 방법으로는 상품 페이지 HTML에서 첫 리뷰 묶음을 파싱할 수 있어요. 이 튜토리얼에서 두 방법을 다 단계별로 다뤘어요.

더 알아보기

Shuai Guan
Shuai Guan
Thunderbit CEO | AI 데이터 자동화 전문가 Shuai Guan은 Thunderbit의 CEO이자 University of Michigan 공학과 출신입니다. 10년 가까운 기술 및 SaaS 아키텍처 경험을 바탕으로, 복잡한 AI 모델을 누구나 바로 활용할 수 있는 노코드 데이터 추출 도구로 바꾸는 데 전문성을 갖고 있습니다. 이 블로그에서는 웹 스크래핑과 자동화 전략에 대한 필터링 없는 실전 경험과 검증된 인사이트를 공유하며, 더 똑똑하고 데이터 중심적인 워크플로를 만드는 데 도움을 드립니다. 데이터 워크플로를 최적화하지 않을 때는, 같은 꼼꼼함으로 사진이라는 취미에 몰두합니다.
목차

말 한마디로 웹페이지를 스크래핑하세요

원하는 걸 평범한 영어로 말하면 됩니다. 아니면 아무 말도 안 해도 괜찮아요.

Thunderbit 사용해보기 무료
AI로 데이터 추출하기
Google Sheets, Airtable, Notion으로 데이터를 손쉽게 منتقل하세요
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week