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

Scrapy爬虫爬取Reclame Aqui投诉链接失败,如何排查并获取全部投诉?

问题:无法爬取Reclame Aqui上桑坦德的未回复投诉链接

我需要爬取网站https://www.reclameaqui.com.br/empresa/santander/lista-reclamacoes/?status=NOT_ANSWERED上的全部未回复客户投诉,编写了如下ComplaintScraper(CrawlSpider)代码:

class ComplaintScraper(CrawlSpider):
    name = "ComplaintScraper"

    allowed_domains = ["https://www.reclameaqui.com.br"]
    start_urls = [
      "https://www.reclameaqui.com.br/empresa/santander/lista-reclamacoes/?status=NOT_ANSWERED",  #Only complaints not answered
      ]
    
    '''
     LinkExtractor: An object which defines how links will be extracted from each crawled page.
    '''
    rules = (
      Rule(LinkExtractor(restrict_css = '#__next > div.sc-1mzw716-0.bbugAk > div.sc-1mzw716-1.dAjixN > div.wydd4i-0.jaTnlr > main > '
        + 'section.wydd4i-5.bDtuKO > div.sc-gJpXkD.ebMJNx.xh9b9g-0.jjQFrx > '
        + 'div.sc-1sm4sxr-0.eFXbXn > div:nth-child(1) > a'), callback = "parse_complaint", follow=True), 
    )

    def start_requests(self):
      for url in self.start_urls:
        yield SplashRequest(url, self.parse_complaint, endpoint='render.html', args={'wait': 0.5})

    def parse_complaint(self, response):
      
      print("Hi", response.url)

但控制台无法输出如下目标投诉链接:

  • https://www.reclameaqui.com.br/santander/desacordo-comercial_EDEwdRrqoHSC5Win/
  • https://www.reclameaqui.com.br/santander/estorno-de-seguro-residencial_RsOgQiG151B-n_x8/
  • https://www.reclameaqui.com.br/santander/do-pix_wylD_ba-c_LBOGQ2/
  • https://www.reclameaqui.com.br/santander/veiculo-quitado_AP-e15Kmdo0zhlqd/
  • ...

请问我代码中的错误在哪里?如何获取该列表中的全部客户投诉?


错误分析与解决方案

1. 错误点梳理

  • allowed_domains格式错误:该参数仅需域名本身,不能带https://,错误格式会导致Scrapy过滤所有符合条件的链接。
  • 重写start_requests破坏CrawlSpider规则逻辑:直接用SplashRequest调用parse_complaint,跳过了CrawlSpider内置的链接提取规则(rules),导致定义的Rule完全失效。
  • CSS选择器脆弱且范围狭窄:使用了动态生成的类名(如sc-1mzw716-0、bbugAk),这类类名会随网站更新变化;同时div:nth-child(1)仅匹配第一个投诉项,无法获取全部链接。
  • 回调函数逻辑冲突:同一个parse_complaint既被用作列表页回调,又被用作详情页回调,逻辑混乱。

2. 修正后的代码

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_splash import SplashRequest

class ComplaintScraper(CrawlSpider):
    name = "ComplaintScraper"

    # 修正allowed_domains,仅保留域名
    allowed_domains = ["www.reclameaqui.com.br"]
    start_urls = [
        "https://www.reclameaqui.com.br/empresa/santander/lista-reclamacoes/?status=NOT_ANSWERED",
    ]

    # 定义链接提取规则:匹配所有投诉详情页链接,使用Splash渲染
    rules = (
        Rule(
            LinkExtractor(allow=r'/santander/[^/]+_[\w-]+/'),
            callback="parse_complaint",
            follow=True,
            process_request='use_splash'  # 指定用Splash处理请求
        ),
        # 分页规则:自动抓取下一页内容
        Rule(
            LinkExtractor(restrict_css='a[aria-label="Próxima página"]'),
            follow=True,
            process_request='use_splash'
        )
    )

    def use_splash(self, request):
        # 封装Splash请求,确保JS渲染完成
        return SplashRequest(
            url=request.url,
            endpoint='render.html',
            args={'wait': 2},  # 延长等待时间,保证页面加载完成
            meta={'original_url': request.url}
        )

    def parse_complaint(self, response):
        # 输出抓取到的详情页URL
        print("已抓取投诉链接:", response.url)
        # 可在此添加投诉内容提取逻辑,如标题、正文、日期等
        # 示例:
        # title = response.css('h1::text').get().strip()
        # content = ' '.join(response.css('.complaint-description ::text').getall()).strip()

3. 关键改动说明

  • 修正域名配置:allowed_domains改为["www.reclameaqui.com.br"],避免合法链接被过滤。
  • Splash与规则集成:通过process_request在Rule中指定Splash处理请求,既保留CrawlSpider的自动爬取逻辑,又实现JS渲染。
  • 稳定的链接匹配:用正则表达式allow=r'/santander/[^/]+_[\w-]+/'匹配所有投诉详情页,比动态CSS选择器更可靠。
  • 分页自动抓取:添加分页链接规则,自动遍历所有页面的未回复投诉。
  • 回调逻辑分离:parse_complaint专门处理详情页,避免逻辑混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:25:27