实战:用 DuckDB 构建跨境电商选品分析器(附完整代码)

实战:用 DuckDB 构建跨境电商选品分析器(附完整代码)

定位:实战项目拆解 目标:教你用 DuckDB 从零搭建一个能直接用于 Amazon/eBay 选品的数据产品原型


为什么选品是赚钱的第一步?

跨境电商的核心不是「卖什么」,而是「卖给谁之前,先搞清楚什么能卖」。

传统选品靠感觉、靠经验、靠刷论坛。而用 DuckDB 做选品分析,你可以在 30 秒内完成过去需要 3 天的数据清洗 + 多维度交叉分析。

今天这篇,我会带你搭建一个完整的选品分析器——它能:

  1. 从 Amazon Best Sellers 页面抓取品类数据(用 httpfs 直接读网页)
  2. 用 Parquet 格式存储和分析百万级 SKU 数据
  3. 通过窗口函数计算品类竞争度、利润率、增速
  4. 输出可执行的选品推荐列表

全程只用 DuckDB SQL,零 Python 依赖(当然也可以用 Python 调用 DuckDB)。


第一步:准备数据

选品分析需要三类数据:

  • 品类数据:Amazon Best Sellers 各品类的 Top 100 商品
  • 评论数据:商品的 Review 数量、评分分布
  • 价格数据:历史价格走势(可以手动录入或用爬虫获取)

为了让你能直接运行,我用 DuckDB 生成模拟数据来演示完整流程。实际使用时,你可以替换为自己的数据源。

import duckdb

con = duckdb.connect("product_selection.duckdb")

# 创建品类表(实际项目中来自 Amazon Best Sellers 抓取)
con.execute("""
CREATE TABLE categories AS
SELECT * FROM (VALUES
    ('Electronics', '手机配件', 15234, 4.2, 892),
    ('Electronics', '蓝牙耳机', 12890, 4.5, 1245),
    ('Electronics', '充电宝', 9876, 4.1, 654),
    ('Home & Kitchen', '厨房小家电', 8543, 4.3, 432),
    ('Home & Kitchen', '收纳用品', 7654, 4.0, 321),
    ('Home & Kitchen', '保温杯', 6543, 4.4, 567),
    ('Sports', '瑜伽用品', 5432, 4.6, 789),
    ('Sports', '健身器材', 4321, 4.2, 234),
    ('Beauty', '护肤工具', 3210, 4.3, 456),
    ('Beauty', '化妆刷', 2109, 4.5, 345),
    ('Toys', '益智玩具', 1987, 4.7, 678),
    ('Toys', '遥控车', 1654, 4.1, 123),
    ('Pet Supplies', '宠物玩具', 1432, 4.4, 234),
    ('Pet Supplies', '猫粮', 3456, 4.6, 890),
    ('Automotive', '车载充电器', 2345, 4.0, 167)
) AS t(category, subcategory, monthly_searches, avg_rating, review_count)
""")

# 创建商品 SKU 表(模拟 5000 个商品)
con.execute("""
CREATE TABLE products AS
SELECT 
    'SKU-' || LPAD(ROW_NUMBER() OVER (), 5, '0') AS sku,
    categories.category,
    categories.subcategory,
    categories.monthly_searches,
    categories.avg_rating,
    categories.review_count,
    ROUND(UNIFORM(5, 200)::DOUBLE, 2) AS price,
    ROUND(UNIFORM(0.1, 0.6)::DOUBLE, 2) AS cost_ratio,
    CASE 
        WHEN UNIFORM(0, 1) > 0.7 THEN '上升'
        WHEN UNIFORM(0, 1) > 0.4 THEN '平稳'
        ELSE '下降'
    END AS trend,
    FLOOR(UNIFORM(10, 500)::INTEGER) AS competitor_count
FROM categories
CROSS JOIN GENERATE_SERIES(1, 350)
""")

运行完上面的代码,你就有了两张表:categories(品类维度)和 products(SKU 维度,共 5000+ 条记录)。


第二步:核心分析引擎

这是选品分析器的核心——用一组 SQL 查询回答「哪些品类值得做」。

2.1 品类竞争力评分

-- 综合评分公式:搜索量权重 + 评分质量 + 竞争度反比
WITH category_scores AS (
    SELECT 
        category,
        subcategory,
        monthly_searches,
        avg_rating,
        review_count,
        competitor_count,
        
        -- 搜索量标准化(0-100)
        ROUND(100.0 * monthly_searches / MAX(monthly_searches) OVER(), 1) AS search_score,
        
        -- 评分质量分
        ROUND(avg_rating * 20, 1) AS rating_score,
        
        -- 竞争度分(竞争者越少分数越高)
        ROUND(100.0 * LEAST(review_count, 1000) / 1000, 1) AS competition_score,
        
        -- 平均售价和成本
        ROUND(AVG(price), 2) AS avg_price,
        ROUND(AVG(price * cost_ratio), 2) AS avg_cost,
        
        -- 毛利率
        ROUND((1 - cost_ratio) * 100, 1) AS gross_margin_pct
        
    FROM products
    GROUP BY category, subcategory, monthly_searches, avg_rating, 
             review_count, competitor_count, cost_ratio, price
)
SELECT 
    *,
    -- 综合得分 = 搜索量(30%) + 评分(20%) + 竞争度(20%) + 毛利率(30%)
    ROUND(
        search_score * 0.3 + 
        rating_score * 0.2 + 
        competition_score * 0.2 + 
        gross_margin_pct * 0.3, 
    1) AS total_score
FROM category_scores
ORDER BY total_score DESC
LIMIT 15;

输出示例:

subcategorymonthly_searchesavg_ratingavg_priceavg_costgross_margin_pcttotal_score
保温杯65434.428.5612.3456.872.3
瑜伽用品54324.635.2115.6755.571.8
猫粮34564.642.1018.9055.169.5

2.2 趋势分析:用窗口函数找「上升赛道」

-- 找出搜索量增长且竞争度低的品类
SELECT 
    category,
    subcategory,
    monthly_searches,
    review_count,
    trend,
    competitor_count,
    
    -- 同品类内排名(按搜索量降序)
    RANK() OVER (PARTITION BY category ORDER BY monthly_searches DESC) AS rank_in_category,
    
    -- 搜索量相对于该品类的占比
    ROUND(100.0 * monthly_searches / SUM(monthly_searches) OVER (PARTITION BY category), 1) AS share_pct,
    
    -- 搜索量与竞争者的比值(越高越好 = 需求大但竞争少)
    ROUND(monthly_searches::DOUBLE / NULLIF(competitor_count, 0), 0) AS demand_competition_ratio
    
FROM products
WHERE trend = '上升'
  AND gross_margin_pct > 45
ORDER BY demand_competition_ratio DESC
LIMIT 10;

关键指标解读:

  • demand_competition_ratio > 10:高需求低竞争,黄金品类
  • demand_competition_ratio 5-10:中等机会
  • demand_competition_ratio < 5:红海市场,谨慎入场

2.3 价格带分析:找到「利润最优价格区间」

-- 将商品按价格分桶,分析各价格带的表现
SELECT 
    CASE 
        WHEN price < 15 THEN '$0-$15'
        WHEN price < 30 THEN '$15-$30'
        WHEN price < 50 THEN '$30-$50'
        WHEN price < 100 THEN '$50-$100'
        ELSE '$100+'
    END AS price_band,
    subcategory,
    COUNT(*) AS product_count,
    ROUND(AVG(gross_margin_pct), 1) AS avg_margin,
    ROUND(AVG(monthly_searches), 0) AS avg_searches,
    ROUND(AVG(competitor_count), 0) AS avg_competitors,
    -- 每个价格带的利润潜力指数
    ROUND(COUNT(*) * AVG(gross_margin_pct) / NULLIF(AVG(competitor_count), 0), 1) AS profit_potential
FROM products
GROUP BY price_band, subcategory
ORDER BY profit_potential DESC
LIMIT 20;

洞察: 通常 $15-$50 价格带是跨境电商的黄金区间——竞争适中、毛利可观、用户决策成本低。


第三步:实战扩展——用 Parquet 处理真实数据

当你有了真实的选品数据(比如几万条 Amazon 商品数据),DuckDB 的 Parquet 支持会让分析速度提升 10 倍以上。

# 1. 将分析结果导出为 Parquet(压缩率极高,体积小)
con.execute("""
COPY (
    SELECT 
        category, subcategory,
        ROUND(AVG(price), 2) AS avg_price,
        ROUND(AVG(gross_margin_pct), 1) AS avg_margin,
        ROUND(AVG(monthly_searches)) AS avg_searches,
        ROUND(AVG(competitor_count)) AS avg_competitors,
        ROUND(
            100.0 * AVG(monthly_searches) / NULLIF(AVG(competitor_count), 0), 1
        ) AS opportunity_score
    FROM products
    GROUP BY category, subcategory
    ORDER BY opportunity_score DESC
) TO 'output/top_opportunities.parquet' (COMPRESSION ZSTD)
""")

# 2. 后续分析直接从 Parquet 文件读取(无需重新计算)
result = con.execute("""
SELECT * FROM read_parquet('output/top_opportunities.parquet')
WHERE opportunity_score > 50
""").fetchdf()

print(result)

Parquet 的优势:

  • 文件体积比 CSV 小 5-10 倍
  • 列式存储,查询指定列时跳过无关数据
  • ZSTD 压缩下,读取速度仍然比 CSV 快 3-5 倍
  • 可以直接用 read_parquet() 读取 S3/GCS 上的远程 Parquet 文件

第四步:进阶——用 httpfs 直接查询网页数据

DuckDB 1.5.x 的 httpfs 扩展让你能直接从 URL 读取数据,无需先下载:

# 直接读取远程 JSON API(比如电商平台的公开数据接口)
con.execute("LOAD httpfs;")

# 示例:读取一个公开的电商数据 API
result = con.execute("""
SELECT * FROM read_json_auto('https://api.example.com/products.json', 
    filename=true,
    union_by_name=true)
LIMIT 100
""").fetchall()

# 或者读取远程 Parquet 文件
result = con.execute("""
SELECT category, COUNT(*), AVG(price)
FROM read_parquet('s3://my-bucket/ecommerce/products/*.parquet')
GROUP BY category
ORDER BY COUNT(*) DESC
""").fetchall()

这意味着你可以:

  1. 用 Python 爬虫抓取 Amazon Best Sellers 页面
  2. 将数据存为 Parquet 上传到 S3
  3. DuckDB 直接查询 S3 上的文件进行分析
  4. 整个流程零数据落地(在内存中完成)

第五步:把这个分析器变成产品

选品分析器本身就是一个可以变现的产品。以下是几种商业化路径:

路径 A:SaaS 工具

将上述 SQL 逻辑封装成 Streamlit 应用,用户上传 CSV/Excel,DuckDB 在内存中完成分析,输出选品报告。定价 $9.99-29.99/月。

路径 B:数据服务

为跨境电商卖家提供定制化的选品分析报告。每次分析收费 $50-200,边际成本几乎为零(DuckDB 处理百万行数据只需几秒)。

路径 C:付费内容/课程

将选品方法论 + DuckDB 实操录制成课程,在 Udemy/Gumroad 上销售,定价 $29.99-49.99。

路径 D:API 服务

将分析引擎封装为 REST API,供 ERP 系统或选品工具调用。


完整项目代码

把所有模块组合起来,得到一个完整的选品分析器:

"""
DuckDB Cross-Border E-commerce Product Selection Analyzer
Usage: python3 product_selector.py [--input products.csv] [--output report.json]
"""
import duckdb
import json
import sys

def build_analyzer(db_path="selection.duckdb"):
    """初始化分析器"""
    con = duckdb.connect(db_path)
    con.execute("LOAD httpfs;")
    con.execute("INSTALL json;")
    con.execute("LOAD json;")
    return con

def run_full_analysis(con):
    """运行完整选品分析"""
    
    # 1. 综合评分
    top_products = con.execute("""
        WITH scored AS (
            SELECT 
                category, subcategory,
                ROUND(AVG(price), 2) AS avg_price,
                ROUND(AVG(cost_ratio * 100), 1) AS cost_pct,
                ROUND(AVG((1 - cost_ratio) * 100), 1) AS margin_pct,
                ROUND(AVG(monthly_searches)) AS avg_searches,
                ROUND(AVG(competitor_count)) AS avg_competitors,
                ROUND(AVG(avg_rating), 1) AS avg_rating,
                ROUND(
                    100.0 * AVG(monthly_searches) / NULLIF(AVG(competitor_count), 0), 1
                ) AS opp_score,
                ROUND(
                    (100.0 * AVG(monthly_searches) / MAX(AVG(monthly_searches)) OVER() * 0.3 +
                     AVG(avg_rating) * 20 * 0.2 +
                     100.0 * LEAST(AVG(competitor_count), 100) / 100 * 0.2 +
                     AVG((1 - cost_ratio) * 100) * 0.3
                    ), 1
                ) AS total_score
            FROM products
            GROUP BY category, subcategory
        )
        SELECT * FROM scored 
        WHERE opp_score > 30 
        ORDER BY total_score DESC
        LIMIT 20
    """).fetchdf()
    
    return top_products.to_dict(orient='records')

# 使用示例
if __name__ == "__main__":
    con = build_analyzer()
    results = run_full_analysis(con)
    print(json.dumps(results[:5], indent=2, ensure_ascii=False))
    con.close()

总结

用 DuckDB 搭建选品分析器的核心思路:

  1. 数据聚合:用 GROUP BY + 窗口函数做多维度交叉分析
  2. 评分建模:用 SQL 表达式直接定义评分公式,无需 Pandas
  3. 高性能:Parquet + ZSTD 压缩,百万级 SKU 秒级分析
  4. 可扩展:httpfs 支持远程数据源,S3/GCS/HTTP 直接查询
  5. 可产品化:分析结果可以直接输出为 API、SaaS、报告

这套模式可以迁移到任何数据分析驱动的变现场景——不仅是电商选品,还包括:

  • 广告投放 ROI 分析
  • 社交媒体热点追踪
  • 竞品价格监控
  • 库存优化预测

关键是:先有数据,再用 DuckDB 快速挖掘其中的赚钱机会。


📖 本文的完整可运行项目代码和数据集已发布在 duckdblab.org,包含 Amazon 真实选品数据的处理示例和 Streamlit 可视化看板搭建教程。

💡 更多 DuckDB 变现案例和实战技巧 → duckdblab.org

📺 Watch video tutorials → Olap Studio YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计

⚠️ 本站为独立社区项目,与 DuckDB 基金会及 DuckDB 官方项目无任何从属、背书或赞助关系。

"DuckDB" 是 DuckDB 基金会的注册商标,本站仅以事实描述方式使用该名称。

本站内容仅供教育与社区推广用途,不构成任何商业服务。