
本文介绍如何使用 Scrapy 无需渲染直接抓取 Anaconda 网站中含多种颜色与尺寸组合的商品变体数据,通过解析页面内嵌的 data-url 和 data-variant-size-code 属性,构建完整变体 URL 并提取标题、原价、促销价及规格信息。
本文介绍如何使用 scrapy 无需渲染直接抓取 anaconda 网站中含多种颜色与尺寸组合的商品变体数据,通过解析页面内嵌的 `data-url` 和 `data-variant-size-code` 属性,构建完整变体 url 并提取标题、原价、促销价及规格信息。
在电商网页中,商品常以“颜色 × 尺寸”形式提供多个变体(如 Mantis Green + 6lb、Spool Yellow + 30lb),而这些变体通常不全部静态渲染在初始 HTML 中,而是通过前端 JS 动态加载。但关键的是:Anaconda 网站将变体跳转链接以 data-url 属性形式预埋在 DOM 中,因此无需依赖 Splash 或 Selenium 等渲染工具,仅用纯 Scrapy 即可高效、稳定地遍历所有组合。
核心策略:分层解析 + URL 构建
- 颜色层优先:从主商品页提取所有 .js-variant-style-picker 元素的 data-url,每个对应一种颜色(如 /.../BP90140299-mantis-green)。Scrapy 使用 response.follow() 递归请求这些颜色专属页。
- 尺寸层展开:在每个颜色页中,定位 .size-variant a 元素,提取其 data-variant-size-code(如 6lb、30lb),拼接为形如 https://www.anacondastores.com/6lb?version=7 的变体 URL。
- 精准字段提取:最终变体页的结构高度统一——所有关键信息(标题、价格、促销价、尺寸)均编码在 #productContentWrapper > div 的 data-* 属性中,CSS 选择器简洁可靠。
完整可运行代码示例
import scrapy
class AnacondaSpider(scrapy.Spider):
name = "anaconda"
allowed_domains = ["www.anacondastores.com"]
# 起始页为任意颜色变体(确保包含完整变体导航)
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:
# 注意:Anaconda 变体API需带 version 参数以保证数据完整性
variant_url = response.urljoin(f"{code}?version=7")
yield scrapy.Request(variant_url, callback=self.parse_size)
def parse_size(self, response):
item = {}
# 所有字段均来自 data-* 属性,稳定且无需文本清洗
item["title"] = response.css("#productContentWrapper > div::attr(data-product-name)").get()
item["price"] = response.css("#productContentWrapper > div::attr(data-product-metric1)").get() # 原价
item["sale_price"] = response.css("#productContentWrapper > div::attr(data-product-price)").get() # 促销价
item["size"] = response.css("#productContentWrapper > div::attr(data-product-dimension13)").get()
# 补充颜色信息(从URL路径提取,确保组合唯一性)
color_match = re.search(r"/([^/]+)$", response.url)
item["color"] = color_match.group(1) if color_match else "unknown"
yield item
关键注意事项与优化建议
- ✅ 避免 Splash:该站点变体数据完全静态化,scrapy-splash 不仅增加部署复杂度,还显著降低抓取速度与稳定性。
- ⚠️ URL 构造严谨性:data-variant-size-code 仅为相对路径片段(如 6lb),必须使用 response.urljoin() 拼接,而非硬编码域名。
- ? 字段可靠性验证:data-product-price 返回的是促销价(若无促销则同原价),data-product-metric1 为划线价;二者均返回字符串(如 "19.99"),后续可 float() 转换。
- ? 组合完整性保障:因颜色页已包含全部尺寸选项,本方案天然覆盖所有 (color, size) 组合(如预期中的 Mantis Green 6lb 至 Spool Yellow 30lb),无需笛卡尔积逻辑。
- ?️ 反爬友好实践:添加 DOWNLOAD_DELAY = 1(在 settings.py 中)及合理 USER_AGENT,遵守 robots.txt,确保长期可维护性。
通过该方法,你不仅能精准获取全部变体数据,还能大幅简化架构、提升性能,并为同类电商网站(尤其采用 data-* 驱动变体的平台)提供可复用的爬取范式。











