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

Scrapy模拟Ajax「Show more results」按钮加载数据问题求助

问题解决:Scrapy抓取CardMarket加载更多内容

核心问题原因

你之前用click()方法是错的——Scrapy本身没有浏览器环境,没法直接模拟前端按钮点击。那个「Show more results」是通过AJAX异步请求加载数据的,得直接抓它的接口请求,而不是操作按钮。

解决步骤

1. 先抓包分析AJAX接口

打开浏览器F12开发者工具,切换到「网络」标签,然后点击页面上的「Show more results」,找到新出现的XHR类型请求:

  • 确认请求URL(一般是带ajax的路径)
  • 查看请求方法(大概率是POST)
  • 提取请求参数:比如start(起始条目数)、limit(每页加载数量),还有可能需要_token这类验证参数(从初始页面的HTML里能拿到)
  • 确认响应格式:一般是JSON或者HTML片段,直接解析即可

2. 修改Scrapy代码实现分页抓取

下面是调整后的代码,核心是先处理当前页数据,再构造AJAX请求加载更多:

# Partie scraping
import scrapy
import logging
from datetime import datetime
from ..items import CardItem

class CardsSpider(scrapy.Spider):
    name = "cards"
    allowed_domains = ["cardmarket.com"]
    start_urls = ["https://www.cardmarket.com/en/Magic/Cards/Chrome-Mox?language=1&minCondition=2"]
    # 假设每页加载20条,根据抓包结果调整
    limit = 20
    start = 0

    def parse(self, response):
        item = CardItem()
        divs = response.xpath("//*[contains(@id, 'articleRow')]")

        # 处理当前页的卡片数据
        for div in divs:
            logging.warning(f"{datetime.now()} 抓取到条目: {div.get()}")
            item['card'] = 'Chrome Mox'
            item['timestampScraped'] = str(datetime.now())
            # 用get()加默认值替代getall()[0],避免空值报错
            item['sellerName'] = div.xpath("div[3]/div/div[1]/span/span/span[3]/a/text()").get(default='未知卖家')
            item['set'] = div.xpath("div[3]/div/div[2]/div/div[1]/a[1]/@href").get(default='未知卡组')
            item['sellerCountry'] = div.xpath("div[3]/div/div[2]/div/div[1]/span[2]/@data-original-title").get(default='未知国家')
            price_text = div.xpath("div[4]/div[1]/div/div/span/text()").get(default='0 €')
            item['price'] = price_text.replace(',', '.').replace(' €', '')
            item['quantity'] = div.xpath("div[4]/div[2]/span/text()").get(default='0')

            yield item

        # 准备加载更多的请求
        self.start += self.limit
        # 从初始页面获取csrf token(根据实际抓包的参数名调整)
        csrf_token = response.xpath("//meta[@name='csrf-token']/@content").get()
        if not csrf_token:
            logging.warning("未获取到CSRF Token,停止加载更多")
            return

        # 构造AJAX请求的URL和参数(根据你抓包的实际情况修改)
        ajax_url = "https://www.cardmarket.com/en/Magic/Cards/Chrome-Mox/ajax"
        form_data = {
            'language': '1',
            'minCondition': '2',
            'start': str(self.start),
            'limit': str(self.limit),
            '_token': csrf_token
        }

        # 发送POST请求加载更多,回调parse方法处理数据
        yield scrapy.FormRequest(
            url=ajax_url,
            formdata=form_data,
            callback=self.parse,
            meta={'start': self.start}
        )

3. 注意事项

  • 抓包时要留意请求头,部分网站会校验Referer、User-Agent,如果请求被拒,要把这些头加到Scrapy请求中
  • 不要用time.sleep(),Scrapy自带并发控制,在settings.py里调整DOWNLOAD_DELAY参数控制请求间隔,避免被封
  • 处理数据时优先用get(default='默认值'),防止空值引发索引错误

基础教程推荐

  • Scrapy官方中文文档:从入门到进阶,覆盖框架核心用法,是最权威的学习资料
  • HTTP请求基础:了解GET/POST请求、请求头、响应体的概念,这是爬虫的核心基础
  • 浏览器抓包教程:熟练使用F12开发者工具分析网络请求,解决异步加载、动态内容的抓取问题
  • XPath选择器教程:掌握用XPath定位HTML元素,这是Scrapy解析页面的关键技能

内容的提问来源于stack exchange,提问作者Grégory Desprez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 12:47:16