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

为何Scrapy在循环未完成时关闭我的爬虫?

爬虫中断循环的原因及解决方法

核心原因:Scrapy默认URL去重机制拦截了重复请求

你每次请求的都是同一个URL https://api.ipify.org/,Scrapy默认启用的URL去重功能(由DUPEFILTER_CLASS控制,默认实现为scrapy.dupefilters.RFPDupeFilter)会自动过滤重复的请求。第一次请求完成后,后续yield的相同URL请求会被直接丢弃,爬虫没有待处理任务就会直接关闭。

次要排查点:代理中间件有效性

如果你的代理地址proxy_ip:proxy_port无效或无法正常连接,也可能导致请求失败,但从日志来看没有报错信息,该可能性较低。可以在代理中间件中添加日志,确认代理是否被正确设置到请求的meta中:

def process_request(self, request, spider):
    if spider.use_proxy:            
        request.meta['proxy'] = 'proxy_ip:proxy_port'
        spider.logger.info(f"Proxy set for request: {request.meta['proxy']}")
    return None

解决办法

方法1:禁用当前爬虫的去重功能

在Spider类中添加custom_settings,全局关闭去重:

class IpSpider(scrapy.Spider):
    name = "ip"
    n = 0
    use_proxy = True
    custom_settings = {
        'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter',
    }

    # 原有start_requests和parse_ip代码不变

方法2:给请求添加随机参数绕过去重

在URL后拼接随机参数,让每次请求的URL唯一:

import random

def parse_ip(self, response):
    if self.n < 10:
        self.n += 1
        self.logger.info(self.n)
        self.logger.info(response.body)
        # 添加随机参数避免URL重复
        url = f"https://api.ipify.org/?t={random.randint(1, 100000)}"
        yield scrapy.Request(url, callback=self.parse_ip)

方法3:针对单个请求禁用去重

在yield Request时设置dont_filter=True,仅让当前请求跳过去重:

yield scrapy.Request(
    "https://api.ipify.org/", 
    callback=self.parse_ip,
    dont_filter=True
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:39:45