You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy多请求数据聚合:将单品多色图片URL合并为单条JSON

解决方案

要实现单个商品的所有颜色图片URL聚合到同一条JSON记录,核心是通过Scrapy的meta参数传递商品的状态信息,逐步收集所有颜色的图片,待所有颜色处理完成后再统一输出记录。

修改后的完整代码

import scrapy

class USSpider(scrapy.Spider):
    name = 'US'
    start_urls = ['https://tr.uspoloassn.com/sadece-online-erkek/?attributes_filterable_product_base_type=T-Shirt']

    def parse(self, response):
        # 获取当前页码和总页数,修正循环范围确保包含最后一页
        current_page = int(response.css('.js-product-list-load::attr(page)').extract_first())
        total_pages = int(response.css('.js-product-list-load::attr(numpages)').extract_first())
        for page_num in range(current_page, total_pages + 1):
            page_url = f"https://tr.uspoloassn.com/sadece-online-erkek/?attributes_filterable_product_base_type=T-Shirt&page={page_num}"
            yield scrapy.Request(url=page_url, callback=self.parse2)

    def parse2(self, response):
        # 简化商品链接遍历逻辑
        for product_href in response.css('a.js-product-images-wrapper::attr(href)'):
            product_url = response.urljoin(product_href.get())
            yield scrapy.Request(url=product_url, callback=self.parse3)

    def parse3(self, response):
        base_product_url = response.url
        # 提取并过滤颜色列表(去重+筛选以v开头的颜色)
        color_list = list(set(response.xpath('//*[@class="js-variant-area "]//a[@class="js-variant "]/@data-value').extract()))
        valid_colors = [color for color in color_list if color.lower().startswith('v')]

        if not valid_colors:
            # 无有效颜色时直接输出空图片列表的商品记录
            yield {
                'product_url': base_product_url,
                'image_links': []
            }
            return

        # 发起第一个颜色的请求,传递商品基础信息、剩余颜色和图片收集容器
        first_color = valid_colors.pop()
        color_url = f"{base_product_url}?integration_color={first_color}"
        yield scrapy.Request(
            url=color_url,
            callback=self.parseImage,
            meta={
                'product_url': base_product_url,
                'remaining_colors': valid_colors,
                'all_images': []
            }
        )

    def parseImage(self, response):
        # 从meta中取出商品状态数据
        product_url = response.meta['product_url']
        remaining_colors = response.meta['remaining_colors']
        all_images = response.meta['all_images']

        # 收集当前颜色的图片链接
        current_color_images = response.css("a.js-product-thumbnail::attr(data-image)").extract()
        all_images.extend(current_color_images)

        if remaining_colors:
            # 还有未处理的颜色,继续发起请求并更新状态
            next_color = remaining_colors.pop()
            next_color_url = f"{product_url}?integration_color={next_color}"
            yield scrapy.Request(
                url=next_color_url,
                callback=self.parseImage,
                meta={
                    'product_url': product_url,
                    'remaining_colors': remaining_colors,
                    'all_images': all_images
                }
            )
        else:
            # 所有颜色处理完成,输出聚合后的商品记录
            yield {
                'product_url': product_url,
                'image_links': all_images
            }

关键改动说明

  1. 状态传递:在parse3中通过meta传递商品的基础URL、剩余未处理的颜色列表,以及用于收集图片的空列表,让每个parseImage请求能跟踪当前商品的处理进度。
  2. 逐步收集图片:每次处理完一个颜色的图片后,将其添加到总图片列表中,若还有剩余颜色则继续发起请求,直到所有颜色处理完毕。
  3. 统一输出:当商品的所有颜色都处理完成后,才输出包含该商品所有图片URL的单条JSON记录。
  4. 代码优化:简化了页码循环、商品链接遍历的逻辑,让代码更易读和维护。

内容的提问来源于stack exchange,提问作者mouhamad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:01:07