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

使用Scrapy爬取ReclameAqui时翻页重复获取第一页内容问题

问题根源及解决办法

核心问题:网站分页机制不支持直接通过URL参数pagina=N获取对应页码

ReclameAqui当前的投诉列表采用动态渲染+API驱动的分页方式,直接访问?pagina=N的URL会被网站忽略参数,强制返回第一页内容——这是你重复获取相同数据的根本原因。

具体问题点排查

  • URL参数无效:网站前端的分页逻辑是通过调用内部API接口实现的,而非解析URL中的pagina参数,直接拼接该参数的请求会被服务器重定向或返回第一页的静态内容。
  • 不必要的dont_filter=True:你在请求中添加了这个参数,但它只是关闭Scrapy的重复请求过滤,无法解决网站本身不识别分页参数的问题。
  • 自定义配置冲突:custom_settings中重复设置了CONCURRENT_REQUESTS_PER_DOMAIN(先设1再设10),虽不直接导致分页问题,但会造成配置混乱,建议删除重复项。

修复方案

方案1:直接调用分页API(推荐,效率更高)

通过浏览器开发者工具(F12 → Network → XHR)抓包,翻页时可以看到网站会请求类似这样的API接口:

https://www.reclameaqui.com.br/api/company/[企业ID]/complaints/?page=2&size=10

Santander的企业ID是11546,所以分页API格式为:

https://www.reclameaqui.com.br/api/company/11546/complaints/?page={页码}&size=10

修改爬虫代码,直接请求该API接口,解析返回的JSON数据:

# 修改start_urls和start_requests
start_urls = [
    "https://www.reclameaqui.com.br/api/company/11546/complaints/?page=1&size=10",
    "https://www.reclameaqui.com.br/api/company/11546/complaints/?page=2&size=10",
    "https://www.reclameaqui.com.br/api/company/11546/complaints/?page=3&size=10"
]

def start_requests(self):
    for url in self.start_urls:
        # 添加必要的请求头,模拟前端请求
        headers = {
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest'
        }
        yield scrapy.Request(url, self.parse_complaint_api, headers=headers)

def parse_complaint_api(self, response):
    data = json.loads(response.text)
    for complaint in data['data']:
        # 直接从API获取投诉详情的链接或字段
        complaint_url = f"https://www.reclameaqui.com.br/reclamacao/{complaint['legacyId']}"
        yield scrapy.Request(complaint_url, callback=self.parse_model_complaint)

方案2:模拟前端翻页(适合坚持爬HTML页面的场景)

如果一定要爬HTML页面,需要通过前端翻页按钮的XPath定位,获取下一页的真实链接(而非手动拼接pagina参数):

def parse_complaint(self, response):
    # 解析当前页的投诉链接
    for row in response.xpath('//div[contains(@class,"bJdtis")]'):
        link = row.xpath("./a/@href").get()
        yield scrapy.Request(response.urljoin(link), callback=self.parse_model_complaint)
    
    # 获取下一页的真实链接
    next_page = response.xpath('//a[contains(@aria-label,"Próxima página")]/@href').get()
    if next_page:
        yield scrapy.Request(response.urljoin(next_page), callback=self.parse_complaint)

这种方式需要确保翻页按钮的XPath正确,且网站没有反爬限制。

额外注意事项

  • 网站有反爬机制,建议增加DOWNLOAD_DELAY到2-3秒,同时设置合理的USER_AGENT模拟真实浏览器请求。
  • 解析__NEXT_DATA__中的JSON数据是正确的方式,因为投诉详情页的内容是通过Next.js预渲染的,该JSON包含所有所需字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:50:37