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

ASP.NET分页爬取重复问题:Scrapy去重失效该如何解决?

解决Scrapy爬取ASP.NET站点时URL相同导致的无限循环问题

嗨,这个问题我太熟悉了!ASP.NET站点依赖__VIEWSTATE、__EVENTTARGET这类表单参数来区分不同请求,而Scrapy默认的去重逻辑只看URL,再加上你代码里用了dont_filter=True直接跳过检查,自然会陷入无限循环。给你几个实用的解决方案:

1. 自定义DupeFilter,基于URL+表单参数组合去重

这是最规范的做法,能让Scrapy的去重机制适配ASP.NET的请求特点。你可以继承Scrapy自带的RFPDupeFilter,重写指纹生成逻辑,把表单里的关键参数(比如__EVENTTARGET、__VIEWSTATE)加入指纹计算:

from scrapy.dupefilters import RFPDupeFilter
from scrapy.utils.request import request_fingerprint

class ASPNetDupeFilter(RFPDupeFilter):
    def request_fingerprint(self, request):
        # 获取请求的表单数据(FormRequest才会有)
        form_data = request.formdata or {}
        # 先生成默认的URL指纹,再拼接排序后的表单参数,确保参数顺序不影响指纹
        base_fp = request_fingerprint(request)
        custom_fp = base_fp + str(sorted(form_data.items())).encode('utf-8')
        return custom_fp

然后在你的项目settings.py里配置使用这个自定义去重器:

DUPEFILTER_CLASS = '你的项目名.dupefilters.ASPNetDupeFilter'  # 替换成实际路径

2. 移除dont_filter=True

你代码里加了这个参数,会让Scrapy完全跳过所有去重检查,这是导致无限循环的直接原因之一。除非你有特殊的跳过需求,否则一定要删掉这个参数,让自定义的DupeFilter发挥作用。

3. 手动跟踪已请求的关键参数(简单场景首选)

如果你的爬虫逻辑比较简单,不想自定义DupeFilter,也可以在爬虫类里维护一个集合,记录已经发送过的__EVENTTARGET值,生成请求前先做检查:

class YourAspSpider(scrapy.Spider):
    name = 'asp_net_spider'
    # 用集合存储已访问过的__EVENTTARGET值,保证查询效率
    visited_event_targets = set()

    def parse(self, response):
        if '1' in page:  # 注意确保page变量已正确定义
            target_links = response.xpath("//a[@class = 'dtgNormalPage']").extract()[1:]
            for link in target_links:
                event_target = link.split("'")[1].replace('$', ':')
                # 检查这个参数是否已经请求过
                if event_target not in self.visited_event_targets:
                    self.visited_event_targets.add(event_target)
                    yield FormRequest.from_response(
                        response,
                        url,
                        callback=self.pages,
                        formdata={'__EVENTTARGET': event_target}
                        # 去掉dont_filter=True!
                    )

这种方法简单直接,不需要修改全局配置,适合小规模的ASP.NET站点爬取。

额外提示

ASP.NET站点的__VIEWSTATE和__VIEWSTATEGENERATOR也是动态变化的,每次请求后都要从响应里提取最新的值,放到下一次请求的formdata里,否则可能会请求失败或者被判定为重复提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:38:15