搜索结果

×

搜索结果将在这里显示。

🌙 shopify采集字段说明

網址:https://www.on.com/en-us/

采集完成數據詳情:samsoe_sales.xls

Shopify 产品导入 CSV 文件字段说明

字段名称 说明
Handle产品唯一标识符(不可重复),通常是产品名称的小写版本,用“-”连接
Title产品标题,显示在商品页面的名称
Body (HTML)产品描述,可包含 HTML 格式
Vendor供应商名称(品牌或制造商)
Type产品类型,用于分类
Tags产品标签,多个标签用逗号分隔
Published是否发布(TRUE = 已发布,FALSE = 未发布)
Option1 Name选项 1 的名称(如颜色、尺寸)
Option1 Value选项 1 的值(如红色、M 号)
Option2 Name选项 2 的名称(如果适用)
Option2 Value选项 2 的值(如果适用)
Option3 Name选项 3 的名称(如果适用)
Option3 Value选项 3 的值(如果适用)
Variant SKU库存单位(SKU),用于追踪库存
Variant Grams变体的重量(以克为单位)
Variant Inventory Tracker库存追踪方式(如 Shopify)
Variant Inventory Qty变体的库存数量
Variant Inventory Policy库存策略(deny = 无库存时不可购买,continue = 无库存仍可下单)
Variant Fulfillment Service履行服务提供商(如 manual 或第三方物流)
Variant Price变体价格(最终售价)
Variant Compare At Price变体的对比价格(原价或折扣前价格)
Variant Requires Shipping是否需要运输(TRUE = 需要,FALSE = 不需要)
Variant Taxable是否需要缴税(TRUE = 需要,FALSE = 不需要)
Variant Barcode变体的条形码(如 UPC、EAN 或 ISBN)
Image Src产品图片 URL(直接可访问)
Image Position图片的显示顺序(数字越小,越靠前)
Image Alt Text图片的替代文本,有助于 SEO 和无障碍访问
Gift Card是否为礼品卡(TRUE = 是,FALSE = 否)
SEO TitleSEO 标题,出现在搜索结果的产品标题
SEO DescriptionSEO 描述,优化搜索引擎的产品简介
Variant Image变体专属图片的 URL(可选)
Status产品状态(active = 已上架,draft = 草稿,archived = 已归档)
Collection产品所属的集合(可选)

示例脚本:

import requests
import json
import time
import csv
from datetime import datetime

def get_product_images(primary_image):
    """根据primaryImage生成1-5的图片链接"""
    images = []
    if primary_image:
        # 从primaryImage中提取基本URL
        # 例如从 https://images.lululemon.com/is/image/lululemon/LW3HQFS_038426_1
        # 提取到 https://images.lululemon.com/is/image/lululemon/LW3HQFS_038426
        base_url = primary_image.rsplit('_', 1)[0]

        # 生成1到5的图片链接
        for i in range(1, 6):
            image_url = f"{base_url}_{i}"
            images.append(image_url)

    return images

def convert_to_shopify_format(product_data):
    """将产品数据转换为Shopify格式"""
    # 打印调试信息
    print(f"\n处理产品: {product_data['displayName']}")

    shopify_product = {
        "title": product_data["displayName"],
        "body_html": "",  # 可以添加产品描述
        "vendor": "lululemon",
        "product_type": product_data["parentCategoryUnifiedId"].replace("-", " ").title(),
        "created_at": datetime.now().isoformat(),
        "handle": product_data["unifiedId"],
        "published_at": datetime.now().isoformat(),
        "template_suffix": "",
        "status": "active",
        "published_scope": "web",
        "tags": [],
        "variants": [],
        "options": [
            {
                "name": "Color",
                "position": 1,
                "values": []
            },
            {
                "name": "Size",
                "position": 2,
                "values": [str(i) for i in range(0, 21, 2)]  # 生成0,2,4,...,20的尺码
            }
        ],
        "images": []
    }

    # 收集所有颜色
    colors = {}  # 用于存储颜色和对应的SKU样式

    # 从 skuStyleOrder 收集颜色信息
    for sku_style in product_data["skuStyleOrder"]:
        # 收集颜色信息
        if sku_style["colorName"] not in colors:
            colors[sku_style["colorName"]] = {
                "colorId": sku_style["colorId"],
                "styleId": sku_style["styleId"]
            }
        if sku_style["colorName"] not in shopify_product["options"][0]["values"]:
            shopify_product["options"][0]["values"].append(sku_style["colorName"])

    # 为每个颜色创建所有尺码的变体
    for color_name, color_info in colors.items():
        # 为每个尺码创建变体
        for size in shopify_product["options"][1]["values"]:
            # 构建SKU
            sku = f"{color_info['styleId']}_{size}"
            variant = {
                "sku": sku,
                "price": product_data["listPrice"][0],
                "compare_at_price": None,
                "option1": color_name,
                "option2": size,
                "available": True,
                "inventory_quantity": 1,
                "requires_shipping": True
            }
            shopify_product["variants"].append(variant)

    print(f"\n创建的变体数量: {len(shopify_product['variants'])}")
    print(f"使用的尺码范围: {shopify_product['options'][1]['values']}")

    # 处理图片 - 使用primaryImage生成1-5的图片链接
    for swatch in product_data["swatches"]:
        if swatch["primaryImage"]:
            images = get_product_images(swatch["primaryImage"])
            # 获取该颜色的所有变体SKU
            color_name = next(name for name, info in colors.items() if info["colorId"] == swatch["colorId"])
            variant_ids = [v["sku"] for v in shopify_product["variants"] if v["option1"] == color_name]

            for idx, img_url in enumerate(images, 1):
                shopify_product["images"].append({
                    "src":img_url,
                    "position": len(shopify_product["images"]) + 1,
                    "variant_ids": variant_ids
                })

    return shopify_product

def write_products_to_csv(products, writer):
    """将产品数据写入CSV文件"""
    for product in products:
        base_row = {
            'Handle': product['handle'],
            'Title': product['title'],
            'Body (HTML)': product['body_html'],
            'Vendor': product['vendor'],
            'Type': product['product_type'],
            'Tags': '',
            'Published': 'TRUE',
            'Option1 Name': 'Color',
            'Option2 Name': 'Size',
            'Option3 Name': '',
            'Option3 Value': '',
            'Variant Grams': '0',
            'Variant Inventory Tracker': 'shopify',
            'Variant Inventory Qty': '100',
            'Variant Inventory Policy': 'deny',
            'Variant Fulfillment Service': 'manual',
            'Variant Requires Shipping': 'TRUE',
            'Variant Taxable': 'TRUE',
            'Variant Barcode': '',
            'Image Alt Text': '',
            'Gift Card': 'FALSE',
            'SEO Title': product['title'],
            'SEO Description': '',
            'Google Shopping / Google Product Category': '',
            'Google Shopping / Gender': '',
            'Google Shopping / Age Group': '',
            'Google Shopping / MPN': '',
            'Google Shopping / AdWords Grouping': '',
            'Google Shopping / AdWords Labels': '',
            'Google Shopping / Condition': '',
            'Google Shopping / Custom Product': '',
            'Google Shopping / Custom Label 0': '',
            'Google Shopping / Custom Label 1': '',
            'Google Shopping / Custom Label 2': '',
            'Google Shopping / Custom Label 3': '',
            'Google Shopping / Custom Label 4': '',
            'Variant Weight Unit': 'g',
            'Variant Tax Code': '',
            'Cost per item': '',
            'Status': 'active'
        }

        # 为每个变体写入一行
        for variant in product['variants']:
            row = base_row.copy()
            row.update({
                'Option1 Value': variant['option1'],
                'Option2 Value': variant['option2'],
                'Variant SKU': variant['sku'],
                'Variant Price': variant['price'],
                'Variant Compare At Price': variant.get('compare_at_price', ''),
            })

            # 查找该变体对应的图片
            variant_images = [img['src'] for img in product['images'] 
                            if variant['sku'] in img['variant_ids']]

            if variant_images:
                # 写入第一张图片信息
                row['Image Src'] = variant_images[0]
                row['Image Position'] = '1'
                row['Variant Image'] = variant_images[0]
                writer.writerow(row)

                # 写入剩余图片
                for idx, img_url in enumerate(variant_images[1:], 2):
                    image_row = {
                        'Handle': product['handle'],
                        'Image Src': img_url,
                        'Image Position': str(idx)
                    }
                    writer.writerow(image_row)
            else:
                # 如果没有图片,仍然写入产品信息
                writer.writerow(row)

def get_lululemon_products():
    url = "https://shop.lululemon.com/snb/graphql"
    page = 1

    # 创建CSV文件和writer对象
csv_filename = f'lululemon_products_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv'
    fieldnames = [
        "Handle", "Title", "Body (HTML)", "Vendor", "Type", "Tags", "Published",
        "Option1 Name", "Option1 Value", "Option2 Name", "Option2 Value",
        "Option3 Name", "Option3 Value", "Variant SKU", "Variant Grams",
        "Variant Inventory Tracker", "Variant Inventory Qty", "Variant Inventory Policy",
        "Variant Fulfillment Service", "Variant Price", "Variant Compare At Price",
        "Variant Requires Shipping", "Variant Taxable", "Variant Barcode",
        "Image Src", "Image Position", "Image Alt Text", "Gift Card",
        "SEO Title", "SEO Description", "Google Shopping / Google Product Category",
        "Google Shopping / Gender", "Google Shopping / Age Group",
        "Google Shopping / MPN", "Google Shopping / AdWords Grouping",
        "Google Shopping / AdWords Labels", "Google Shopping / Condition",
        "Google Shopping / Custom Product", "Google Shopping / Custom Label 0",
        "Google Shopping / Custom Label 1", "Google Shopping / Custom Label 2",
        "Google Shopping / Custom Label 3", "Google Shopping / Custom Label 4",
        "Variant Image", "Variant Weight Unit", "Variant Tax Code",
        "Cost per item", "Status"
    ]

    with open(csv_filename, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()

        headers = {
            "accept": "application/graphql+json, application/json",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "content-type": "application/json",
            "origin": "https://shop.lululemon.com",
            "priority": "u=1, i",
            "referer": "https://shop.lululemon.com/c/women-clothes/n14uwk",
            "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Microsoft Edge";v="132"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"Windows"',
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors", 
            "sec-fetch-site": "same-origin",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0",
            "x-lll-referrer": "Channel=Web,Page=CDP",
            "x-lll-request-correlation-id": "029b94b5-e82d-463b-84e0-a787e2e72aea"
        }

        while True:
            payload = {
                "query": """query CategoryPageDataQuery($category:String!,$cid:String,$forceMemberCheck:Boolean,$nValue:String,$cdpHash:String,$sl:String!,$locale:String!,$Ns:String,$storeId:String,$pageSize:Int,$page:Int,$onlyStore:Boolean,$useHighlights:Boolean,$abFlags:[String],$styleboost:[String],$fusionExperimentVariant:String){categoryPageData(category:$category nValue:$nValue cdpHash:$cdpHash locale:$locale sl:$sl Ns:$Ns page:$page pageSize:$pageSize storeId:$storeId onlyStore:$onlyStore forceMemberCheck:$forceMemberCheck cid:$cid useHighlights:$useHighlights abFlags:$abFlags styleboost:$styleboost fusionExperimentVariant:$fusionExperimentVariant){activeCategory allLocaleNvalues{CA US __typename}categoryLabel fusionExperimentId fusionExperimentVariant fusionQueryId h1Title isBopisEnabled isFusionQuery isWMTM name results:totalProducts totalProductPages currentPage type bopisProducts{allAvailableSizes currencyCode defaultSku displayName listPrice parentCategoryUnifiedId productOnSale:onSale productSalePrice:salePrice pdpUrl productCoverage repositoryId:productId productId inStore unifiedId highlights{highlightLabel highlightIconWeb priority visibility subText abFlag{abFlagName showIcon showHighlight showSubText visibility __typename}__typename}skuStyleOrder{colorGroup colorId colorName inStore size sku skuStyleOrderId styleId01 styleId02 styleId __typename}swatches{primaryImage hoverImage url colorId inStore __typename}__typename}storeInfo{totalInStoreProducts totalInStoreProductPages storeId __typename}products{allAvailableSizes currencyCode defaultSku displayName intendedCupSize listPrice parentCategoryUnifiedId productOnSale:onSale productSalePrice:salePrice pdpUrl productCoverage repositoryId:productId productId inStore unifiedId highlights{highlightLabel highlightIconWeb priority visibility subText abFlag{abFlagName showIcon showHighlight showSubText visibility __typename}__typename}skuStyleOrder{colorGroup colorId colorName inStore size sku skuStyleOrderId styleId01 styleId02 styleId __typename}swatches{primaryImage hoverImage url colorId inStore __typename}__typename}seoLinks{next prev self __typename}__typename}}""",
                "operationName": "CategoryPageDataQuery",
                "variables": {
                    "nValue": None,
                    "cdpHash": "n14uwk",
                    "category": "women-clothes",
                    "locale": "en_US",
                    "sl": "US",
                    "page": page,
                    "pageSize": 12,
                    "forceMemberCheck": False,
                    "abFlags": ["cdpSeodsEnabled"],
                    "useHighlights": True
                }
            }

            try:
                print(f"正在获取第 {page} 页数据...")
                response = requests.post(url, headers=headers, json=payload)
                response.raise_for_status()
                data = response.json()

                # 检查是否还有产品数据
                if not data["data"]["categoryPageData"]["products"]:
                    break

                # 转换产品数据并直接写入CSV
                products = [convert_to_shopify_format(product) for product in data["data"]["categoryPageData"]["products"]]
                write_products_to_csv(products, writer)
                print(f"第 {page} 页数据已写入CSV文件")

                page += 1
                time.sleep(1)  # 添加延迟,避免请求过快

            except requests.exceptions.RequestException as e:
                print(f"请求失败: {e}")
                break
            except Exception as e:
                print(f"处理数据时出错: {e}")
                break

        print(f"数据已保存到 {csv_filename}")

if __name__ == "__main__":
    get_lululemon_products()