搜索结果

×

搜索结果将在这里显示。

🐠 chewy

geturl

import requests
import json

# GraphQL请求URL
url = "https://www.chewy.com/api/pdp/graphql"

# 请求头
headers = {
    "accept": "*/*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "apollo-require-preflight": "true",
    "content-type": "application/json",
    "origin": "https://www.chewy.com",
    "priority": "u=1, i",
    "referer": "https://www.chewy.com/jespet-4-wheel-pet-stroller-maroon-36/dp/211142",
    "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"',
    "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-dtpc": "3$469704714_962h77vCVHABIHTOUWKPNCUNIGUOHUFUDJKVQGB-0e0"
}

# GraphQL查询
query = """
mutation PDP_AddToCart($input: AddToCartInput!) {
  addToCart(input: $input) {
    updated {
      ...PDP_Cart__CartItem
      __typename
    }
    cart {
      ...PDP_Cart
      __typename
    }
    __typename
  }
}

fragment PDP_Cart__CartItem on CartItem {
  id
  item {
    ...PDP_Cart__Item
    __typename
  }
  partNumber
  price
  quantity
  subtotal
  customizedAttributes {
    personalizedThumbnailUrl
    __typename
  }
  __typename
}

fragment PDP_Cart__Item on Item {
  id
  isVetDiet
  isPrescription
  ...PDP_SmartShelf__AddedItem
  ...PDP_Analytics__Item
  __typename
}

fragment PDP_SmartShelf__AddedItem on Item {
  fullImage {
    url(autoCrop: true, square: 144)
    __typename
  }
  entryID
  partNumber
  name
  product {
    name
    id
    manufacturerName
    __typename
  }
  isPrescription
  isGiftCard
  isBundleMultiSku
  isPersonalized
  is3DCustomizable
  bundleTitle
  offerPrice
  __typename
}

fragment PDP_Analytics__Item on Item {
  id
  entryID
  advertisedPrice
  definingAttributeValues: attributeValues(
    usage: [DEFINING]
    includeEnsemble: true
  ) {
    ...PDP_Analytics__AttributeValue
    __typename
  }
  is3DCustomizable
  isPersonalized
  is3DCustomizable
  images {
    ...PDP_CarouselImage
    meta: url(maxHeight: 630)
    metaLarge: url(square: 1800, autoCrop: true)
    __typename
  }
  shelterImages: images {
    main: url(autoCrop: true, square: 600)
    __typename
  }
  parentCatalogGroupId
  name
  onSpecial
  partNumber
  product {
    ...PDP_Analytics__Product
    __typename
  }
  strikeThroughPrice
  isGiftCard
  isAutoshipAllowed
  inStock
  isPrescription
  masterCatalogIdentifier
  __typename
}

fragment PDP_Analytics__AttributeValue on AttributeValue {
  id
  value
  attribute {
    id
    name
    __typename
  }
  __typename
}

fragment PDP_CarouselImage on Image {
  __typename
  thumbnail: url(autoCrop: true, square: 108)
  main: url(autoCrop: true, sideLongest: 600)
  magnified: url(autoCrop: true, sideLongest: 1200)
  magnifiedModal: url(autoCrop: true, sideLongest: 1800)
}

fragment PDP_Analytics__Product on Product {
  id
  entryID
  manufacturerName
  name
  partNumber
  slug
  rating
  ratingCount
  breadcrumbs {
    ...Breadcrumb
    __typename
  }
  __typename
}

fragment Breadcrumb on Breadcrumb {
  id
  name
  url
  __typename
}

fragment PDP_Cart on Cart {
  id
  subtotal
  totalQuantity
  freeShippingAmount
  freeShippingEligibleAmount
  freeShippingThresholdAmount
  shippingPrice
  hasGiftCard
  __typename
}
"""

# 请求体
payload = {
    "operationName": "PDP_AddToCart",
    "variables": {
        "input": {
            "items": [
                {
                    "partNumber": "1060313",
                    "quantity": 1,
                    "attributes": {}
                }
            ]
        }
    },
    "extensions": {},
    "query": query
}

try:
    # 发送POST请求
    response = requests.post(url, headers=headers, json=payload)

    # 检查响应状态码
    response.raise_for_status()

    # 打印响应内容
    print(json.dumps(response.json(), indent=2, ensure_ascii=False))

except requests.exceptions.RequestException as e:
    print(f"请求发生错误: {e}")
except json.JSONDecodeError as e:
    print(f"JSON解析错误: {e}") 
    print(f"JSON解析错误: {e}") 

获取商品信息

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

# GraphQL请求URL
url = "https://www.chewy.com/api/pdp/graphql"

# 请求头
headers = {
    "accept": "*/*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "apollo-require-preflight": "true",
    "content-type": "application/json",
    "origin": "https://www.chewy.com",
    "priority": "u=1, i",
    "referer": "https://www.chewy.com/jespet-4-wheel-pet-stroller-maroon-36/dp/211142",
    "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"',
    "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-dtpc": "3$469704714_962h77vCVHABIHTOUWKPNCUNIGUOHUFUDJKVQGB-0e0"
}

# GraphQL查询 - 获取产品详情
product_query = """
query PDP_SmartShelf($partNumber: String!, $promotionId: String, $includePetsAndClinics: Boolean!, $loyaltyFeaturesEnabled: Boolean!) {
  cart {
    id
    ...PDP_SmartShelf__Cart
    items {
      ...PDP_ItemCartUpdateInfo
      __typename
    }
    __typename
  }
  smartShelf(partNumber: $partNumber, promotionId: $promotionId) {
    currentItem {
      id
      ...PDP_SmartShelf__Item
      images {
        url
        thumbnail: url(autoCrop: true, square: 108)
        main: url(autoCrop: true, sideLongest: 600)
        magnified: url(autoCrop: true, sideLongest: 1200)
        magnifiedModal: url(autoCrop: true, sideLongest: 1800)
        __typename
      }
      __typename
    }
    promotion {
      ...PDP_SmartShelf__Promotion
      __typename
    }
    promotionItemsInCartCount
    __typename
  }
  userData {
    membershipStatus @include(if: $loyaltyFeaturesEnabled)
    __typename
  }
  currentUser {
    clinicOrgs {
      ...PDP_ClinicOrgs @include(if: $includePetsAndClinics)
      __typename
    }
    __typename
  }
}

fragment PDP_SmartShelf__Cart on Cart {
  ...PDP_Cart
  __typename
}

fragment PDP_Cart on Cart {
  id
  subtotal
  totalQuantity
  freeShippingAmount
  freeShippingEligibleAmount
  freeShippingThresholdAmount
  shippingPrice
  hasGiftCard
  __typename
}

fragment PDP_ItemCartUpdateInfo on CartItem {
  cartId
  quantity
  item {
    id
    partNumber
    __typename
  }
  __typename
}

fragment PDP_SmartShelf__Item on Item {
  id
  description
  fullImage {
    url(autoCrop: true, square: 400)
    __typename
  }
  freeShippingThreshold
  name
  advertisedPrice
  partNumber
  mapEnforced
  mapEnforcedText
  mapSavings
  entryID
  isPrescription
  isPersonalized
  product {
    id
    entryID
    manufacturerName
    rating
    ratingCount
    slug
    petType: attributes(identifier: "PetType") {
      values {
        id
        value
        __typename
      }
      __typename
    }
    definingAttributes: attributes(usage: [DEFINING], includeEnsemble: true) {
      id
      name
      values {
        id
        value
        __typename
      }
      __typename
    }
    __typename
  }
  minimumPetWeights {
    name
    id
    identifier
    values {
      id
      value
      __typename
    }
    __typename
  }
  maximumPetWeights {
    name
    id
    identifier
    values {
      id
      value
      __typename
    }
    __typename
  }
  strikeThroughPrice
  __typename
}

fragment PDP_SmartShelf__Promotion on Promotion {
  id
  condition
  helperText
  isSmartshelfEligible
  longDescription
  name
  promotionType
  reward
  rewardType
  shortDescription
  __typename
}

fragment PDP_ClinicOrgs on ClinicOrg {
  name
  phoneNumber
  postalCode
  communicationPreference
  id
  __typename
}
"""

def get_product_data(part_number):
    # 获取产品详情的请求
    payload = {
        "operationName": "PDP_SmartShelf",
        "variables": {
            "partNumber": part_number,
            "promotionId": "11309",
            "includePetsAndClinics": False,
            "loyaltyFeaturesEnabled": True
        },
        "extensions": {},
        "query": product_query
    }

    try:
        response = requests.post(url, headers=headers, json=payload)
        print(f"Response status code: {response.status_code}")
        print(f"Response headers: {response.headers}")
        response.raise_for_status()
        data = response.json()
        print(f"Response data: {json.dumps(data, indent=2)}")
        return data
    except Exception as e:
        print(f"Error fetching data for part number {part_number}: {e}")
        if hasattr(e, 'response') and e.response is not None:
            print(f"Error response: {e.response.text}")
        return None

def get_variant_partnumbers(product_data):
    """从产品数据中提取所有颜色变体的partnumber"""
    variant_partnumbers = []
    if not product_data or 'data' not in product_data:
        return variant_partnumbers

    try:
        # 从购物车数据中获取其他颜色变体的partnumber
        cart_items = product_data.get('data', {}).get('cart', {}).get('items', [])
        for item in cart_items:
            if item.get('item', {}).get('partNumber'):
                variant_partnumbers.append(item['item']['partNumber'])
    except Exception as e:
        print(f"Error getting variant partnumbers: {e}")

    return variant_partnumbers

def get_color_variants(product_data):
    """从产品数据中提取所有颜色变体信息"""
    variants = []
    if not product_data or 'data' not in product_data:
        return variants

    try:
        current_item = product_data['data']['smartShelf']['currentItem']
        if current_item and current_item.get('product'):
            # 获取当前颜色和partnumber
            current_partnumber = current_item['partNumber']
            current_color = None

            # 获取所有颜色变体信息
            defining_attrs = current_item['product'].get('definingAttributes', [])
            for attr in defining_attrs:
                if attr['name'] == 'Color':
current_color = attr['values'][0]['value']
                    # 获取所有颜色变体
                    for value in attr['values']:
                        if value['value'] != current_color:
                            variants.append({
                                'color': value['value'],
                                'partnumber': value['id']  # 使用ID作为partnumber
                            })
                    break

            # 如果在购物车中有其他变体,也添加进去
            cart_items = product_data.get('data', {}).get('cart', {}).get('items', [])
            for item in cart_items:
                if item.get('item', {}).get('partNumber') and item['item']['partNumber'] != current_partnumber:
                    variants.append({
                        'partnumber': item['item']['partNumber']
                    })
    except Exception as e:
        print(f"Error getting color variants: {e}")

    return variants

def convert_to_shopify_format(product_data):
    if not product_data or 'data' not in product_data or not product_data['data'].get('smartShelf', {}).get('currentItem'):
        return None

    try:
        item = product_data['data']['smartShelf']['currentItem']
        product = item['product']

        # Get pet types
        pet_types = []
        if 'petType' in product:
            for pet_type in product['petType']:
                for value in pet_type['values']:
                    pet_types.append(value['value'])

        # Get attributes as tags
        tags = []
        if 'definingAttributes' in product:
            for attr in product['definingAttributes']:
                if attr['name'] and attr['values']:
                    for value in attr['values']:
                        tags.append(f"{attr['name']}:{value['value']}")

        # Add rating and rating count to tags if available
        if product.get('rating') and product.get('ratingCount'):
            tags.append(f"Rating:{product['rating']}")
            tags.append(f"Reviews:{product['ratingCount']}")

        # Add pet types to tags
        tags.extend(pet_types)

        # 获取所有颜色变体
        colors = []
        if 'definingAttributes' in product:
            for attr in product['definingAttributes']:
                if attr['name'] == 'Color':
                    colors = [value['value'] for value in attr['values']]
                    break

        # 如果没有找到颜色变体,则至少包含当前颜色
        if not colors:
            colors = [""]

        result_rows = []

        # 获取所有图片URL
        images = item.get('images', [])

        # 为每个颜色创建一行数据
        for color in colors:
            # 创建基础数据
            row_data = {
                "Handle": f"chewy-{item['partNumber']}",
                "Title": item['name'],
                "Body (HTML)": item['description'] if item.get('description') else "",
                "Vendor": product['manufacturerName'],
                "Type": " > ".join(pet_types) if pet_types else "Pet Supplies",
                "Tags": ", ".join(tags),
                "Published": "TRUE",
                "Option1 Name": "Color",
                "Option1 Value": color,
                "Option2 Name": "",
                "Option2 Value": "",
                "Option3 Name": "",
                "Option3 Value": "",
                "Variant SKU": f"{item['partNumber']}",
                "Variant Grams": "0",
                "Variant Inventory Tracker": "shopify",
                "Variant Inventory Qty": "10",
                "Variant Inventory Policy": "deny",
                "Variant Fulfillment Service": "manual",
                "Variant Price": item['advertisedPrice'].replace('$', '') if item.get('advertisedPrice') else "",
                "Variant Compare At Price": item['strikeThroughPrice'].replace('$', '') if item.get('strikeThroughPrice') else "",
                "Variant Requires Shipping": "TRUE",
                "Variant Taxable": "TRUE",
                "Variant Barcode": "",
                "Image Position": "",
                "Image Alt Text": item['name'],
                "Gift Card": "FALSE",
                "SEO Title": item['name'],
                "SEO Description": item['description'] if item.get('description') else "",
                "Google Shopping / Google Product Category": "Pet Supplies",
                "Google Shopping / Gender": "",
                "Google Shopping / Age Group": "",
                "Google Shopping / MPN": item['partNumber'],
                "Google Shopping / AdWords Grouping": "",
                "Google Shopping / AdWords Labels": "",
                "Google Shopping / Condition": "New",
                "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": "g",
                "Variant Tax Code": "",
                "Cost per item": "",
                "Status": "active"
            }

            # 只为第一个颜色添加图片信息
            if color == colors[0] and images:
                # 第一行包含完整的产品信息和第一张图片
                row_data["Image Src"] = images[0].get('magnifiedModal', '')
                row_data["Image Position"] = "1"
                result_rows.append(row_data)

                # 后续行只包含图片信息
                for i, image in enumerate(images[1:], 2):
                    image_row = {
                        "Handle": row_data["Handle"],
                        "Image Src": image.get('magnifiedModal', ''),
                        "Image Position": str(i),
                        "Image Alt Text": row_data["Image Alt Text"]
                    }
                    result_rows.append(image_row)
            else:
                # 其他颜色只添加基本信息,不包含图片
                result_rows.append(row_data)

        return result_rows
    except Exception as e:
        print(f"Error converting data to Shopify format: {e}")
        print(f"Product data: {json.dumps(product_data, indent=2)}")
        return None

def main():
    # 读取partnumbers
    with open('chewy_partnumbers.txt', 'r') as f:
        part_numbers = [line.strip() for line in f if line.strip()]

    # 准备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"]

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_file = f'chewy_products_{timestamp}.csv'

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

        for part_number in part_numbers:
            print(f"\nProcessing part number: {part_number}")
            product_data = get_product_data(part_number)
            if product_data and product_data.get('data', {}).get('smartShelf', {}).get('currentItem'):
                shopify_data_rows = convert_to_shopify_format(product_data)
                if shopify_data_rows:
                    for row in shopify_data_rows:
                        writer.writerow(row)
            time.sleep(2)

    print(f"\nCompleted! Results saved to {output_file}")

if __name__ == "__main__":
    main()