本文介绍如何通过分析网页源码和网络请求,精准抓取 anaconda 商品页面中所有颜色与尺寸组合对应的标题、原价、促销价等结构化数据,避免依赖 splash 渲染,提升爬虫稳定性与执行效率。
本文介绍如何通过分析网页源码和网络请求,精准抓取 anaconda 商品页面中所有颜色与尺寸组合对应的标题、原价、促销价等结构化数据,避免依赖 splash 渲染,提升爬虫稳定性与执行效率。
在电商网站如 Anaconda(anacondastores.com)中,商品常以“颜色 × 尺寸”形式提供多个变体(variants),而这些变体信息通常不直接渲染在初始 HTML 中,而是通过前端 JavaScript 动态加载或由 AJAX 请求按需获取。盲目使用 Splash 等 JS 渲染工具不仅增加复杂度与资源开销,还易因等待时机不当导致数据遗漏。
核心思路:逆向分析变体加载机制
通过浏览器开发者工具(Network → XHR/JS Fetch)观察用户点击颜色/尺寸选项时触发的真实请求,可发现变体数据实际来自一组结构化 API 接口,其 URL 通常嵌入在 DOM 元素的 data-url 或 data-variant-* 属性中。本例中:
- 颜色选项(如 Mantis Green、Spool Yellow)对应独立 URL,可通过 .js-variant-style-picker::attr(data-url) 提取;
- 尺寸选项(如 6lb、8lb)则通过 标签的 data-variant-size-code 属性标识,拼接后形成完整变体请求地址(如 /{code}?version=7)。
以下为优化后的 Scrapy 爬虫实现(无需 Splash):
import scrapy
class AnacondaSpider(scrapy.Spider):
name = "anaconda"
allowed_domains = ["www.anacondastores.com"]
# 起始 URL 使用带颜色后缀的页面(确保 color 变体已加载)
start_urls = [
"https://www.anacondastores.com/fishing/fishing-line/braid-line/shimano-kairiki-8-braid-line-150-metre-spool/BP90140299-mantis-green"
]
def parse(self, response):
# ✅ 步骤1:提取所有颜色变体 URL 并递归跟进
color_urls = response.css(".js-variant-style-picker::attr(data-url)").getall()
for url in color_urls:
if url:
yield response.follow(url, callback=self.parse)
# ✅ 步骤2:提取当前颜色页下的所有尺寸编码,并构造变体请求
size_codes = response.css(".size-variant a::attr(data-variant-size-code)").getall()
for code in size_codes:
if code:
# 拼接尺寸变体 URL(注意 version 参数为必需)
variant_url = response.urljoin(f"{code}?version=7")
yield scrapy.Request(
url=variant_url,
callback=self.parse_size,
# 可选:添加 headers 模拟真实浏览器请求
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
)
def parse_size(self, response):
item = {}
# ✅ 直接从页面根节点 data 属性提取结构化商品信息(更稳定可靠)
wrapper = response.css("#productContentWrapper > div").attrib
item["title"] = wrapper.get("data-product-name", "").strip()
item["price"] = wrapper.get("data-product-metric1", "").strip() # 原价(含货币符号)
item["sale_price"] = wrapper.get("data-product-price", "").strip() # 折扣价
item["size"] = wrapper.get("data-product-dimension13", "").strip()
item["color"] = response.url.split("-")[-1].split("?")[0] # 从 URL 解析当前颜色(如 mantis-green → Mantis Green)
# ✅ 补充:规范化颜色名称(可选)
color_map = {
"mantis-green": "Mantis Green",
"spool-yellow": "Spool Yellow",
# 可扩展其他映射
}
item["color"] = color_map.get(item["color"], item["color"].replace("-", " ").title())
yield item
关键注意事项与最佳实践:
- ? 避免 Splash 依赖:该站点变体数据均存在于初始响应的 HTML 或后续轻量级 JSON 接口中,JS 渲染纯属冗余;
- ? URL 构造需严谨:data-variant-size-code 值必须与 ?version=7 拼接,否则返回 404 或默认 SKU;
- ? 颜色解析要健壮:推荐从 response.url 提取颜色标识符并做映射,而非依赖 CSS 选择器(易受 DOM 结构变动影响);
- ? 错误处理不可少:生产环境应添加 try/except 包裹属性访问,并对空值做默认填充(如 item.setdefault("price", "N/A"));
- ? 遵守 robots.txt 与速率限制:添加 custom_settings = {"DOWNLOAD_DELAY": 1} 并检查 https://anacondastores.com/robots.txt。
最终输出将覆盖全部组合(如 "Mantis Green 6lb"、"Spool Yellow 30lb"),每条记录包含准确的标题、原价、促销价及规格维度,为库存监控、比价分析或价格追踪提供高质量数据基础。











