eBay 경쟁자 가격 시각화: 원시 JSONL에서 Price Trend Dashboard까지
I’m unable to retrieve the article’s contents from the link you provided. Could you please paste the text you’d like translated here? Once I have the content, I’ll translate it into Korean while preserving the formatting, markdown syntax, and technical terms as requested.
Source: …
설정
우리는 Ebay.com‑Scrapers 저장소를 사용할 것입니다. 이 저장소에는 eBay 구조에 최적화된, 프로덕션 수준의 스크래퍼가 포함되어 있습니다.
사전 요구 사항
- Python 3.8 이상
- ScrapeOps API 키 (봇 차단 우회용) – 여기에서 발급받으세요
- 기본 터미널 사용 능력
설치
# 저장소 복제
git clone https://github.com/scraper-bank/Ebay.com-Scrapers.git
cd Ebay.com-Scrapers/python/playwright/product_data
# 의존성 설치
pip install playwright playwright-stealth pandas streamlit
# Playwright가 사용할 Chromium 브라우저 설치
playwright install chromium
우리는 playwright/product_data 구현을 사용합니다. 이 구현은 productId, price, availability와 같은 세부 정보를 추출하며, 이는 시계열 추적에 필수적입니다.
경쟁자를 위한 스크래퍼 설정
기본 스크래퍼는 개별 URL을 처리합니다. 경쟁자를 추적하려면 정기적으로 제품 페이지 목록에 대해 스크래퍼를 실행하십시오.
run_tracker.py 라는 래퍼 스크립트를 만들어 대상 URL을 순회하고 결과를 저장합니다. 스크래퍼는 파일 이름에 자동으로 타임스탬프를 추가합니다(예: ebay_com_product_page_scraper_data_20260116_090000.jsonl), 이를 통해 과거 데이터를 쉽게 추적할 수 있습니다.
# run_tracker.py
import asyncio
from scraper.ebay_com_scraper_product_v1 import extract_data, API_KEY
from playwright.async_api import async_playwright
# List of competitor product URLs to monitor
COMPETITOR_URLS = [
"https://www.ebay.com/itm/123456789012",
"https://www.ebay.com/itm/987654321098",
]
async def run_monitoring_session():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
for url in COMPETITOR_URLS:
print(f"Scraping competitor: {url}")
await page.goto(url)
data = await extract_data(page)
# Data saving is handled by the DataPipeline class in the core scraper
print(f"Extracted Price: {data.price} {data.currency}")
await browser.close()
if __name__ == "__main__":
asyncio.run(run_monitoring_session())
데이터 구조 이해
스크래퍼는 JSONL (JSON Lines) 파일을 출력합니다 – 대용량 가격 추적 데이터셋에 메모리 효율적인 스트리밍 형식입니다.
예시 레코드
{
"productId": "123456789012",
"name": "Apple iPhone 15 Pro - 128GB - Blue Titanium",
"price": 899.0,
"currency": "USD",
"availability": "in_stock",
"seller": { "name": "TopTierElectronics", "rating": 99.8 }
}
핵심 세부 사항
- 가격 정리 – 스크래퍼는
"$899.00"와 같은 문자열을 부동소수점(899.0)으로 변환합니다. - 재고 상태 – 경쟁업체가
out_of_stock상태가 되면 차트에서 이를 어떻게 표시할지 결정합니다(예: 선을 끊거나 0값을 플롯).
Pandas를 이용한 데이터 수집 및 정리
각 스크래퍼 실행은 새로운 파일을 생성합니다. 첫 번째 단계는 모든 파일을 하나의 연대순 DataFrame으로 병합하는 것입니다. 파일 이름에서 타임스탬프를 추출하여 시간 축을 구성합니다.
import pandas as pd
import glob
import re
import json
from datetime import datetime
def load_historical_data(directory="./"):
"""Load all JSONL files generated by the scraper into a single DataFrame."""
all_data = []
# Find all JSONL files matching the scraper’s naming pattern
files = glob.glob(f"{directory}/ebay_com_product_page_scraper_data_*.jsonl")
for file in files:
# Extract timestamp from filename: e.g., 20260116_090000
match = re.search(r'(\d{8}_\d{6})', file)
if not match:
continue
timestamp = datetime.strptime(match.group(1), "%Y%m%d_%H%M%S")
with open(file, "r", encoding="utf-8") as f:
for line in f:
item = json.loads(line)
item["scrape_timestamp"] = timestamp
all_data.append(item)
df = pd.DataFrame(all_data)
# Ensure price is numeric
df["price"] = pd.to_numeric(df["price"], errors="coerce")
return df
Streamlit으로 대시보드 만들기
이제 제품 이름으로 필터링하고 일별·주별 가격 변동을 확인할 수 있는 시각적 인터페이스를 만듭니다.
dashboard.py
import streamlit as st
import pandas as pd
# Load the helper function from the previous section
from load_data import load_historical_data # adjust import path as needed
st.set_page_config(page_title="eBay Price Tracker", layout="wide")
st.title("📈 eBay Competitor Price Trends")
# Load data
df = load_historical_data()
# Sidebar filters
available_products = df["name"].unique()
selected_products = st.sidebar.multiselect(
"Select Products to Track",
options=available_products,
default=available_products[:2],
)
filtered_df = df[df["name"].isin(selected_products)]
# Main chart
if not filtered_df.empty:
# Pivot data so each product has its own time series
pivot = (
filtered_df.pivot_table(
index="scrape_timestamp",
columns="name",
values="price",
aggfunc="first",
)
.sort_index()
)
st.line_chart(pivot)
else:
st.info("No data available for the selected products.")
대시보드 실행:
streamlit run dashboard.py
이제 다음과 같은 인터랙티브 대시보드를 사용할 수 있습니다:
- 선택한 경쟁 제품의 가격 추세를 표시합니다.
- 새로운 JSONL 파일이 나타나면 자동으로 업데이트됩니다(페이지를 새로 고침하면 됩니다).
- 라인 차트에 빈 구간이 생겨 재고 부족 기간을 강조합니다.
추가 가격 히스토리 차트 (선택 사항)
# each product has its own column for the line chart
chart_data = filtered_df.pivot(
index='scrape_timestamp',
columns='name',
values='price'
)
st.subheader("Price History")
st.line_chart(chart_data)
# Metrics
cols = st.columns(len(selected_products))
for i, product in enumerate(selected_products):
latest_price = filtered_df[filtered_df['name'] == product].iloc[-1]['price']
cols[i].metric(label=product[:30] + "...", value=f"${latest_price}")
else:
st.write("Please select a product to see the price trend.")
대시보드를 실행하려면:
streamlit run dashboard.py
워크플로 자동화
대시보드는 데이터가 최신일 때만 유용합니다. 매일 아침 스크래퍼를 수동으로 실행하는 것은 비효율적입니다.
Linux / macOS
cron 작업을 설정하여 run_tracker.py 스크립트를 6 시간마다 실행합니다:
0 */6 * * * /usr/bin/python3 /path/to/run_tracker.py
Windows
작업 스케줄러를 사용하여 동일한 결과를 얻을 수 있습니다. 자동화가 완료되면, Streamlit 대시보드는 페이지를 새로 고칠 때마다 최신 가격 데이터를 업데이트합니다.
마무리
우리는 단순 데이터 추출에서 기능적인 비즈니스 도구 구축으로 이동했습니다. ScrapeOps eBay 저장소의 스크래핑 기능과 Pandas 및 Streamlit의 분석 능력을 결합하여 이제 맞춤형 가격 인텔리전스 플랫폼을 갖게 되었습니다.
주요 요점
- JSONL은 효율적 – 시계열 스크래핑 데이터를 기록하기에 최적의 포맷입니다.
- 파일명 타임스탬프 – 파일명에 메타데이터를 저장하면 내부 JSON 구조가 변경될 경우 데이터 손실을 방지할 수 있습니다.
- 시각화가 작동 – 라인 차트에서 5 % 가격 하락을 보는 것이 원시 텍스트 파일을 스캔하는 것보다 훨씬 쉽게 조치를 취할 수 있습니다.
봇 방지 조치를 우회하는 방법에 대해 더 알아보려면 eBay Scraping Breakdown를 확인하세요.