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

如何使用Scrapy获取HTML源码中未显示的页面数据?

解决Scrapy爬取始祖鸟页面商品数据的问题

问题核心分析

页面源码中无商品数据,是因为该页面采用客户端渲染(CSR):初始HTML仅包含页面框架,商品数据由浏览器加载JavaScript后,通过AJAX请求后端接口获取并动态渲染到页面上。懒加载可能是附加场景(滚动加载更多商品),但初始商品列表同样是通过接口异步加载的,这才是你用CSS选择器无法获取数据的根本原因。

解决方案

1. 直接爬取后端API接口(推荐)

这是最高效、稳定的方式,无需处理JS渲染:

  • 打开浏览器开发者工具(F12),切换到Network标签,刷新目标页面;
  • 筛选XHR/Fetch类型的请求,查找包含product、list、catalog等关键词的接口(比如始祖鸟的商品列表接口通常是/api/v1/catalog/products这类格式);
  • 查看请求的URL、请求头(尤其是Authorization、Cookie等可能的验证字段)和返回的JSON数据,里面会包含完整的商品信息(ID、名称、价格、详情链接、图片等);
  • 在Scrapy中直接请求该API接口,解析JSON响应:
    import scrapy
    
    class ArcteryxSpider(scrapy.Spider):
        name = "arcteryx"
        start_urls = ["https://arcteryx.com/de/de/api/v1/catalog/products?category=mens-new-arrivals&..."] # 替换为实际API地址
    
        def parse(self, response):
            data = response.json()
            for product in data.get("products", []):
                yield {
                    "id": product.get("id"),
                    "name": product.get("name"),
                    "price": product.get("price"),
                    "detail_url": f"https://arcteryx.com/de/de/p/{product.get('slug')}"
                    # 提取其他所需字段
                }
    

2. 使用JS渲染工具(如Scrapy-Playwright)

如果API接口有签名验证、反爬机制难以绕过,可以用浏览器渲染页面,获取JS执行后的完整HTML:

  • 安装依赖:pip install scrapy-playwright
  • 在Scrapy项目的settings.py中配置:
    DOWNLOAD_HANDLERS = {
        "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
        "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    }
    PLAYWRIGHT_LAUNCH_OPTIONS = {"headless": True} # 无头模式,如需可视化调试设为False
    
  • 编写爬虫代码,启用Playwright渲染:
    import scrapy
    
    class ArcteryxSpider(scrapy.Spider):
        name = "arcteryx"
        start_urls = ["https://arcteryx.com/de/de/c/mens/new-arrivals?intcmp=home_t1_c_mens_new-arrivals"]
    
        def start_requests(self):
            for url in self.start_urls:
                yield scrapy.Request(url, meta={"playwright": True}, callback=self.parse)
    
        def parse(self, response):
            # 此时response已包含JS渲染后的HTML
            products = response.css('div[class^="LazyProductTile__Wrap"]')
            for product in products:
                yield {
                    "name": product.css("h3::text").get().strip(),
                    "price": product.css("span[class*='Price']::text").get().strip(),
                    "detail_url": product.css("a::attr(href)").get()
                }
    

3. 处理懒加载场景

如果页面需要滚动到底部才加载更多商品,可通过Playwright模拟滚动:

async def parse(self, response):
    page = response.meta["playwright_page"]
    # 多次滚动+等待,确保加载所有商品
    for _ in range(3):
        await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
        await page.wait_for_timeout(2000) # 等待2秒让新内容加载
    # 重新获取渲染后的HTML
    rendered_content = await page.content()
    selector = scrapy.Selector(text=rendered_content)
    products = selector.css('div[class^="LazyProductTile__Wrap"]')
    # 后续商品提取逻辑同前

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:44:52