如何获取Shopify店铺所有商品的ID、标题及变体ID与公开标题
看起来你已经搞定了单个商品的变体提取,很棒!要扩展到整个店铺的所有商品,咱们可以分两步走:先拿到店铺里所有商品的URL,再逐个复用你现有的逻辑提取变体数据。下面是具体的实现思路和代码示例:
方案一:通过店铺Sitemap批量获取(无需API权限)
这种方法适合没有Shopify后台访问权限的情况,大多数公开的Shopify店铺都会生成sitemap.xml来收录所有商品链接。
步骤1:解析Sitemap获取所有商品URL
先请求店铺的sitemap,从中提取所有商品页面的链接:
import requests import xml.etree.ElementTree as ET import time import re import json # 替换成目标Shopify店铺的域名(不带末尾斜杠) SHOPIFY_STORE_URL = "https://your-store.myshopify.com" sitemap_url = f"{SHOPIFY_STORE_URL}/sitemap.xml" def get_all_product_urls(): product_urls = [] try: response = requests.get(sitemap_url, timeout=10) response.raise_for_status() root = ET.fromstring(response.text) # 处理Shopify sitemap的命名空间 namespace = {"ns": "http://www.sitemaps.org/schemas/sitemap/0.9"} # 筛选所有商品页面链接(包含/products/路径) for url in root.findall(".//ns:url", namespace): loc = url.find("ns:loc", namespace).text if "/products/" in loc: product_urls.append(loc) return product_urls except Exception as e: print(f"获取Sitemap失败: {str(e)}") return []
步骤2:遍历商品URL提取变体数据
复用你现有的正则解析逻辑,遍历所有商品URL,注意添加延时避免触发反爬:
def extract_variants_from_product(url): variants = [] raw_sizes = [] try: session = requests.Session() r = session.get(url, timeout=10) r.raise_for_status() html = r.text # 匹配页面中的meta数据(你的原有逻辑) json_pattern = re.compile('var meta = ({.*?});', re.DOTALL) matches = json_pattern.search(html) if not matches: print(f"无法在页面{url}中找到meta数据") return variants, raw_sizes shopify_data = json.loads(matches.group(1)) # 提取变体ID和公开标题 for variant in shopify_data['product']['variants']: variants.append(variant['id']) raw_sizes.append(variant['public_title']) return variants, raw_sizes except Exception as e: print(f"处理页面{url}失败: {str(e)}") return variants, raw_sizes # 主执行逻辑 if __name__ == "__main__": all_product_urls = get_all_product_urls() print(f"共找到{len(all_product_urls)}个商品") # 存储所有变体数据 all_variants = [] all_raw_sizes = [] for idx, url in enumerate(all_product_urls): print(f"正在处理第{idx+1}/{len(all_product_urls)}个商品: {url}") variants, sizes = extract_variants_from_product(url) all_variants.extend(variants) all_raw_sizes.extend(sizes) # 添加1-2秒延时,降低反爬风险 time.sleep(1.5) # 输出结果示例 print("所有变体ID:", all_variants) print("所有公开标题:", all_raw_sizes)
方案二:使用Shopify官方API(推荐,更稳定)
如果你有该店铺的后台访问权限,能拿到API密钥和密码,用官方API会更可靠——无需解析HTML,直接获取结构化数据,还能拿到更多商品关联信息:
import requests SHOPIFY_STORE_URL = "https://your-store.myshopify.com" API_VERSION = "2024-07" # 替换为最新的API版本 API_KEY = "your-api-key" PASSWORD = "your-api-password" def get_all_variants_via_api(): all_variants = [] page = 1 while True: api_url = f"{SHOPIFY_STORE_URL}/admin/api/{API_VERSION}/products.json?limit=250&page={page}" response = requests.get(api_url, auth=(API_KEY, PASSWORD), timeout=10) response.raise_for_status() data = response.json() products = data['products'] if not products: break # 没有更多商品时停止分页 # 提取每个商品的变体数据 for product in products: for variant in product['variants']: all_variants.append({ "variant_id": variant['id'], "public_title": variant['public_title'], "product_title": product['title'] # 额外关联商品标题,方便后续整理 }) page += 1 return all_variants # 使用示例 if __name__ == "__main__": variants_data = get_all_variants_via_api() for item in variants_data: print(f"商品标题: {item['product_title']}, 变体ID: {item['variant_id']}, 公开标题: {item['public_title']}")
关键注意事项
- 反爬限制:Shopify会对高频请求进行拦截,批量爬取时一定要加延时,大数量爬取可以考虑使用代理池。
- 页面结构变化:正则解析HTML的方法依赖店铺主题的渲染结构,如果店铺修改了主题,可能导致匹配失败,API方案则不受此影响。
- 密码保护店铺:如果店铺设置了访问密码,无论是Sitemap还是页面请求都会失败,需要先获取访问权限。
内容的提问来源于stack exchange,提问作者J P
相关产品推荐
相关产品推荐

