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

使用Scrapy中间件处理Indeed爬虫URL时出现无限循环求助

问题分析与解决

无限循环的根本原因

你的中间件判断逻辑太粗糙:仅通过字符串包含检查域名是否存在,但当ScrapeOps代理中间件处理请求后,URL会被替换为代理服务的地址(格式类似http://xxx.proxy.com/https://fr.indeed.com/xxx),此时原域名https://fr.indeed.com不在代理URL中,你的中间件会再次拼接域名,生成https://fr.indeed.comhttp://xxx.proxy.com/https://fr.indeed.com/xxx这类错误URL,进而触发重复处理,陷入无限循环。

此外,字符串包含的判断方式本身就不准确——如果某URL的参数里碰巧包含fr.indeed.com,也会出现误判。

修复后的中间件代码

改用urllib.parse判断URL是否为绝对路径,仅对相对路径进行域名拼接:

from urllib.parse import urlparse

class IndeedDomainVerificationMiddleware:
 
    def __init__(self, indeed_domain_url):
        self.indeed_domain_url = indeed_domain_url.rstrip('/')  # 移除末尾斜杠,避免重复拼接
 
    @classmethod
    def from_crawler(cls, crawler):
        return cls(indeed_domain_url=crawler.settings.get('INDEED_DOMAIN_URL'))
 
    def process_request(self, request, spider):
        if spider.name != 'Indeed':
            return None
            
        parsed_url = urlparse(request.url)
        # 仅当URL是相对路径(无协议和域名)时才拼接
        if not parsed_url.scheme and not parsed_url.netloc:
            # 兼容开头不带斜杠的相对路径(如"cmd/jobs")
            if not request.url.startswith('/'):
                new_url = f"{self.indeed_domain_url}/{request.url}"
            else:
                new_url = f"{self.indeed_domain_url}{request.url}"
            return request.replace(url=new_url)
        return None

额外优化点

  1. 在__init__中给域名移除末尾斜杠,避免生成https://fr.indeed.com//cmd/jobs这类带重复斜杠的无效URL。
  2. 提前判断爬虫名称,不符合则直接返回,减少不必要的逻辑执行。

为什么改Spider中间件没用?

Spider中间件仅处理爬虫生成的Request和返回的Response,而代理中间件属于下载中间件,请求仍会先经过代理处理导致URL被修改,进而再次触发错误判断。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:52:25