Scrapy单爬虫单次调用如何实现多数据源同时正常爬取
多站点单爬虫爬取失败的解决方案
你遇到的问题本质是单站点调试通过的逻辑没有做多站点适配:三个站点的参数规则、页面结构、反爬策略完全独立,直接把URL塞到同一个列表里用统一逻辑发起请求、解析内容,必然会出现全部请求失败的情况。以下是两种可直接落地的方案:
方案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字段名,单站点调试时抓包确认实际参数名再填。
- 重写爬虫的
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
- 提前排查几个高频失败点:
- 不要用同一套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
相关产品推荐
相关产品推荐

