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

Scrapy异常时入队新URL及HTTP/HTTPS自动适配技术咨询

Scrapy爬虫异常处理与协议自动切换方案

嘿,针对你提到的两个Scrapy问题,我给你整理了具体的实现方案,直接看代码和解释就行:

一、爬虫发生异常时,把新URL加入请求队列

在Scrapy里,我们可以给每个Request绑定一个errback回调函数——这个函数专门用来处理请求失败的情况。当请求触发异常时,errback会被调用,我们就在这个函数里构造新的URL,然后yield出新的Request对象,Scrapy就会自动把这个新URL加入请求队列继续处理了。

给你写个示例代码,一看就懂:

import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError, ConnectionRefusedError, TimeoutError

class MySpider(scrapy.Spider):
    name = "myspider"
    
    def start_requests(self):
        # 初始请求,绑定错误回调
        yield scrapy.Request(
            url="https://example.com/target",
            callback=self.parse,
            errback=self.handle_error,
            meta={"original_url": "https://example.com/target"}  # 传递原始URL,方便后续处理
        )
    
    def parse(self, response):
        # 正常解析页面的逻辑
        self.logger.info(f"成功拿到响应: {response.url}")
    
    def handle_error(self, failure):
        failed_url = failure.request.url
        self.logger.error(f"请求炸了: {failed_url}")
        
        # 可以针对性捕获不同异常(可选,也可以直接处理所有异常)
        if failure.check(HttpError):
            self.logger.error(f"HTTP错误,状态码: {failure.value.response.status}")
        elif failure.check(DNSLookupError):
            self.logger.error("DNS解析失败,可能域名写错了?")
        elif failure.check(ConnectionRefusedError):
            self.logger.error("连接被拒绝,服务器可能拦截了?")
        elif failure.check(TimeoutError):
            self.logger.error("请求超时了,服务器反应太慢")
        
        # 构造新URL,这里示例是加个重试参数,你可以根据需求改
        new_url = f"{failed_url}?retry=1"
        # 生成新请求,继续加入队列
        yield scrapy.Request(
            url=new_url,
            callback=self.parse,
            errback=self.handle_error,
            meta={"original_url": failed_url}
        )

二、自动切换HTTP/HTTPS协议的完整实现

针对你给出的代码片段,我帮你完善了逻辑:优先尝试HTTPS请求,一旦失败就自动切换成HTTP再试,还加了重复失败URL的过滤,避免死循环。直接看完整代码:

import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError, ConnectionRefusedError, TimeoutError

class MySpider(scrapy.Spider):
    name = "myspider"
    
    def __init__(self, category=None):
        self.failed_urls = []  # 记录已经处理过的失败URL,防止重复请求
    
    def start_requests(self):
        # 初始优先发起HTTPS请求,这里可以扩展成多个URL
        target_urls = ['https://www.wsiltv.com/random']
        for url in target_urls:
            yield scrapy.Request(
                url=url,
                callback=self.parse,
                errback=self.switch_to_http,
                meta={"original_protocol": "https"}  # 标记初始用的是HTTPS
            )
    
    def parse(self, response):
        self.logger.info(f"搞定!成功获取响应: {response.url}")
        # 这里写你的页面解析逻辑,比如提取数据、跟进链接之类的
        pass
    
    def switch_to_http(self, failure):
        request = failure.request
        original_url = request.url
        
        # 先检查这个URL是不是已经处理过了,避免重复切换协议
        if original_url in self.failed_urls:
            self.logger.warning(f"这个URL已经失败过了,跳过: {original_url}")
            return
        
        self.failed_urls.append(original_url)
        self.logger.error(f"HTTPS请求失败: {original_url},马上切换成HTTP试试")
        
        # 把HTTPS替换成HTTP,生成新请求
        if original_url.startswith("https://"):
            http_url = original_url.replace("https://", "http://", 1)
            yield scrapy.Request(
                url=http_url,
                callback=self.parse,
                errback=self.handle_final_failure,  # HTTP请求也失败的话,走最终错误处理
                meta={"original_protocol": "http"}
            )
        else:
            self.logger.error(f"不是HTTPS请求,没法切换协议: {original_url}")
    
    def handle_final_failure(self, failure):
        failed_http_url = failure.request.url
        self.logger.error(f"HTTP请求也凉了: {failed_http_url},放弃处理这个URL了")
        # 这里可以加后续处理,比如把失败URL写到文件里,方便后续排查
        # with open('failed_urls.txt', 'a') as f:
        #     f.write(f"{failed_http_url}\n")

这个逻辑很清晰:先试HTTPS,失败就切HTTP;如果HTTP也失败,就记录日志或者做其他收尾工作。而且用self.failed_urls列表存已经处理过的失败URL,不会重复请求同一个URL,避免浪费资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:27:03