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

Scrapy单爬虫单次调用如何实现多数据源同时正常爬取

多站点单爬虫爬取失败的解决方案

你遇到的问题本质是单站点调试通过的逻辑没有做多站点适配:三个站点的参数规则、页面结构、反爬策略完全独立,直接把URL塞到同一个列表里用统一逻辑发起请求、解析内容,必然会出现全部请求失败的情况。以下是两种可直接落地的方案:


方案1:单爬虫适配多站点(推荐,符合单命令启动需求)

不需要拆分爬虫,只要给每个站点做独立的请求配置、解析分支即可,步骤如下:

  1. 重构原有URL配置字典,不要只存裸URL,要给每个站点单独配置参数规则、请求头、专属解析方法映射,参考配置:
url_dict = {
    'tshirt': {
        'killler': [
            {
                "url": "https://www.qrx.com/products",
                "params": {"category": "tshirt", "brand": "killler"},
                "callback": "parse_qrx",
                "headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"}
            },
            {
                "url": "https://www.pqr123.com/product",
                "params": {"cat": "tshirt", "b": "killler"},
                "callback": "parse_pqr123",
                "headers": {}
            },
            {
                "url": "https://www.abc213.com/product",
                "params": {"cate": "tshirt", "brandName": "killler"},
                "callback": "parse_abc213",
                "headers": {}
            }
        ]
    }
}

注意:不同站点的查询参数名大概率不一致,不要硬套统一的category/brand字段名,单站点调试时抓包确认实际参数名再填。

  1. 重写爬虫的start_requests方法,为每个站点构造独立请求,绑定对应解析逻辑,参考代码:
import scrapy

class LoungeflySpider(scrapy.Spider):
    name = "loungefly"

    def __init__(self, category=None, brand=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.category = category
        self.brand = brand
        self.site_configs = url_dict.get(category, {}).get(brand, [])

    def start_requests(self):
        for config in self.site_configs:
            yield scrapy.Request(
                url=config["url"],
                callback=getattr(self, config["callback"]),
                headers=config.get("headers", {}),
                cb_kwargs={"params": config.get("params", {})},
                dont_filter=True
            )

    # 三个站点分别写独立的解析方法,不要用统一parse方法硬套所有页面
    def parse_qrx(self, response, params):
        # 仅编写www.qrx.com对应的页面解析、分页逻辑,提取数据后yield Item即可
        pass

    def parse_pqr123(self, response, params):
        # 仅编写www.pqr123.com对应的解析逻辑
        pass

    def parse_abc213(self, response, params):
        # 仅编写www.abc213.com对应的解析逻辑
        pass
  1. 提前排查几个高频失败点:
  • 不要用同一套XPath/CSS选择器解析所有站点,三个站点DOM结构完全不同,统一选择器必然提取不到数据
  • 调整爬虫配置避免被拦截:在settings.py中将CONCURRENT_REQUESTS设为2-3,DOWNLOAD_DELAY设为1-3秒,避免并发过高被站点封禁
  • 不要省略必要请求头:部分站点需要携带Referer、指定UA才能返回正常内容,单站点调试时浏览器自动携带的请求头,批量请求时要手动补上
  • 加dont_filter=True避免重复过滤器误判:Scrapy默认的去重规则可能把不同站点、路径相似的请求判定为重复请求直接丢弃

方案2:拆分独立爬虫+批量启动脚本(适合站点逻辑差异极大的场景)

如果三个站点的反爬逻辑、登录要求、分页规则差异过大,没必要硬塞在同一个爬虫内,可以为每个站点写独立的Spider类,再通过脚本批量启动,同样能实现单次执行爬取所有站点的效果:
编写启动脚本run_all.py:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

if __name__ == "__main__":
    process = CrawlerProcess(get_project_settings())
    # 注册三个站点的独立爬虫,传入相同参数,统一输出到data.jl
    process.crawl("qrx_spider", category="tshirt", brand="killler", output="data.jl")
    process.crawl("pqr123_spider", category="tshirt", brand="killler", output="data.jl")
    process.crawl("abc213_spider", category="tshirt", brand="killler", output="data.jl")
    process.start()

直接执行python run_all.py即可依次跑完三个站点的爬取任务,各站点逻辑完全隔离,不会互相干扰,维护成本更低。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:57:19