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
相关产品推荐
相关产品推荐

