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

Scrapy爬取Etsy搜索页与分类页产品数量差异问题排查

Etsy爬取产品数量不足的问题分析与解决方案

问题原因

  1. CSS选择器匹配不全
    你用的div.js-merch-stash-check-listing仅匹配了部分产品容器,Etsy搜索页和分类页的DOM结构存在差异:分类页部分产品用这个类,但搜索页的产品容器类名不同(比如可能是div.v2-listing-card),导致大量产品被遗漏。

  2. 动态加载时机未适配
    Etsy产品采用滚动加载机制,仅靠wait:2的固定等待时间不足以让单页所有产品加载完成。尤其是搜索页加载策略更严格,需触发滚动事件才会加载后续产品,单纯等待无法触发加载逻辑。

  3. 反爬机制限制
    Splash默认请求头(如User-Agent)可能被Etsy识别为非真实浏览器,导致返回内容被截断,仅展示少量产品;同时未维护会话Cookie也可能导致页面内容不完整。

可行解决方案

1. 修正CSS选择器,覆盖所有产品容器

放弃依赖特定类名,改用产品节点的通用属性匹配——所有产品都带有data-listing-id属性,用这个定位更可靠:

div[data-listing-id]

同时检查每个字段的选择器兼容性,比如搜索页的产品名称可能用h2.wt-text-body而非h3.wt-text-caption,需做兼容处理。

2. 优化Splash配置,模拟滚动加载

用Lua脚本模拟页面滚动,触发所有产品的加载逻辑,替换单纯的wait参数。示例代码如下:

def start_requests(self):
    lua_script = """
    function main(splash, args)
        splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
        splash:go(args.url)
        splash:wait(2)
        -- 模拟滚动3次,每次滚动到底部并等待加载
        for i=1,3 do
            splash:runjs("window.scrollTo(0, document.body.scrollHeight);")
            splash:wait(2)
        end
        return splash:html()
    end
    """
    for url in self.start_urls:
        yield SplashRequest(
            url,
            self.parse,
            endpoint='execute',
            args={'lua_source': lua_script},
            meta={'splash': {'resource_timeout': 30}}
        )

3. 配置真实请求头与会话

在Splash请求中添加真实浏览器的User-Agent,避免被反爬识别;同时启用Splash的Cookie管理,保持会话一致性,确保页面返回完整内容。

4. 调试验证方法

  • 直接访问Splash渲染页面:http://localhost:8050/execute?lua_source=[你的Lua脚本]&url=[目标URL],查看渲染后的HTML是否包含所有产品,以此判断是加载问题还是选择器问题。
  • 在Spider中打印response.text长度或保存为HTML文件,对比手动浏览的页面内容,定位差异点。

修改后的示例Spider代码

import scrapy
from scrapy_splash import SplashRequest
import logging

class EtsySpider(scrapy.Spider):
    name = 'etsy'
    # 同时测试分类页和搜索页
    start_urls = [
        'https://www.etsy.com/uk/c/electronics-and-accessories/gadgets?ref=catnav-11049',
        'https://www.etsy.com/uk/search?q=gadgets&ref=search_bar'
    ]

    item_id = 0

    def start_requests(self):
        lua_script = """
        function main(splash, args)
            splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            splash:go(args.url)
            splash:wait(2)
            for i=1,3 do
                splash:runjs("window.scrollTo(0, document.body.scrollHeight);")
                splash:wait(2)
            end
            return splash:html()
        end
        """
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
                endpoint='execute',
                args={'lua_source': lua_script},
                meta={'splash': {'resource_timeout': 30}}
            )
            self.log(f"Splash request sent: {url}", level=logging.INFO)

    def parse(self, response):
        # 用通用属性定位所有产品
        for product in response.css('div[data-listing-id]'):
            # 兼容不同页面的名称选择器
            name = product.css('h3.wt-text-caption::text, h2.wt-text-body::text').get()
            if not name:
                continue
            # 兼容分类页和搜索页的category获取
            if 'search' in response.url:
                category = response.css('#global-enhancements-search-query::attr(value)').get()
            else:
                category = response.css('span.wt-breadcrumb__text::text').getall()[-1]
            
            yield {
                'id': self.item_id,  
                'name': name.strip(),
                'category': category.strip() if category else 'Unknown',
                'price': product.css('span.currency-value::text').get(),
                'item_link': product.css('a.listing-link::attr(href)').get(),
                'img_link': product.css('img.wt-width-full::attr(src)').get(),
                'listing_id': product.css('::attr(data-listing-id)').get()
            }
            self.item_id += 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:35:22