我们知道,现在运行Scrapy项目中的爬虫文件,需要一个一个地运行,那么是否可以将对应的爬虫文件批量运行呢?如果可以,又该怎么实现呢?在Scrapy中,如果想批量运行爬虫文件,常见的有两种方法:
现在我们创建一个新的爬虫项目,用于实现爬虫多开技能:
scrapy startproject multi_spiders
然后,进入该爬虫项目所在目录,并在该项目中创建3个爬虫文件,如下所示:
vagrant@homestead:~/spider/multi_spiders$ scrapy genspider first_spider baidu.com
Created spider 'first_spider' using template 'basic' in module:
multi_spiders.spiders.first_spider
vagrant@homestead:~/spider/multi_spiders$ scrapy genspider second_spider baidu.com
Created spider 'second_spider' using template 'basic' in module:
multi_spiders.spiders.second_spider
vagrant@homestead:~/spider/multi_spiders$ scrapy genspider third_spider baidu.com
Created spider 'third_spider' using template 'basic' in module:
multi_spiders.spiders.third_spider
此时,我们已经在项目中创建了3个爬虫文件,有了这些转呗工作之后,我们就可以正式进入运行多个爬虫文件的功能的编写。
CrawProcess为scrapy.spiders
模块下的一个工具类,要实现爬虫多开技能,我们需要先将其导入进来,并且实例化。下面新建一个Python文件multi_manager.py
,用于实现爬虫多开操作,实现多开操作的具体代码如下:
# -*- coding: UTF-8 -*-
from multi_spiders.spiders.first_spider import FirstSpiderSpider
from multi_spiders.spiders.second_spider import SecondSpiderSpider
from multi_spiders.spiders.third_spider import ThirdSpiderSpider
from scrapy.crawler import CrawlerProcess
process = CrawlerProcess()
# 将三个爬虫类依次添加进来
process.crawl(FirstSpiderSpider)
process.crawl(SecondSpiderSpider)
process.crawl(ThirdSpiderSpider)
process.start()
运行此模块会发现,三个爬虫都被运行了。
Scrapy是开源的,如果要实现运行多个爬虫文件,我们参考crawl命令的源码,进行相应的修改,并写一个自己的Python文件,这相当于定义了一个心明了,所以还需要使用Scrapy添加自定义命令的功能为我们所写的代码添加一个自定义命令。然后就可以根据这个自定义命令,运行多个爬虫文件。
crawl命令的源码可以在Scrapy官方的GitHub项目中找到(地址市:https://github.com/scrapy/scrapy/blob/master/scrapy/commands/crawl.py
),找到并打开该源码文件,具体代码如下所示:
import os
from scrapy.commands import ScrapyCommand
from scrapy.utils.conf import arglist_to_dict
from scrapy.utils.python import without_none_values
from scrapy.exceptions import UsageError
class Command(ScrapyCommand):
...
def run(self, args, opts):
if len(args) < 1:
raise UsageError()
elif len(args) > 1:
raise UsageError("running 'scrapy crawl' with more than one spider is no longer supported")
spname = args[0]
self.crawler_process.crawl(spname, **opts.spargs)
self.crawler_process.start()
部分与我们不相关的代码,我就不贴出来了,有兴趣的同学可以自己上去看一下。这里,我们主要看Command类下面的run()
方法,run()
方法中指定了要运行哪些爬虫文件,具体通过crawler_process.crawl(spname, **opts.spargs)
实现爬虫文件的运行,spname指的是爬虫名称。所以,我们要实现一次运行多个爬虫文件,关键需要修改run()
方法。
首先,我们进入到项目目录multi_spiders
,而后进入multi_spiders
,在这里新建一个文件夹,如下:
vagrant@homestead:~/spider/multi_spiders/multi_spiders$ mkdir mycmd
然后,进入新建的文件夹mycmd
并创建一个Python文件,名字可自定义:
vagrant@homestead:~/spider/multi_spiders/multi_spiders/mycmd$ vi mycrawl
将crawl命令的源码复制此文件中,并对run()方法进行如下修改:
import os
from scrapy.commands import ScrapyCommand
from scrapy.utils.conf import arglist_to_dict
from scrapy.utils.python import without_none_values
from scrapy.exceptions import UsageError
class Command(ScrapyCommand):
...
def run(self, args, opts):
spname_list = self.crawl_process.spider_loader.list()
for spname in spname_list():
self.crawl_process.crawl(spname, **opts.spargs)
self.crawler_process.start()
然后在该文件的同级目录下添加一个初始化文件__init__.py
。随后我们还需要在项目的配置文件settings.py
中进行相应配置,定义命令源码目录,如下所示:
COMMANDS_MODULE = 'multi_spiders.mycmd'
随后,我们退回到项目所在目录,并输入scrapy -h,将会出现如下所示信息:
vagrant@homestead:~/spider/multi_spiders$ scrapy -h
Scrapy 1.4.0 - project: multi_spiders
Usage:
scrapy [options] [args]
Available commands:
bench Run quick benchmark test
check Check spider contracts
crawl Run a spider
edit Edit spider
fetch Fetch a URL using the Scrapy downloader
genspider Generate new spider using pre-defined templates
list List available spiders
mycrawl Run a spider
parse Parse URL (using its spider) and print the results
runspider Run a self-contained spider (without creating a project)
settings Get settings values
shell Interactive scraping console
startproject Create new project
version Print Scrapy version
view Open URL in browser, as seen by Scrapy
Use "scrapy -h" to see more info about a command
可以看到,此时已经出现自定义命令mycrawl
了。随后我们就可以使用该自定义命令同时启动所有的爬虫文件了,如下所示:
vagrant@homestead:~/spider/multi_spiders$ scrapy mycrawl --nolog
此时已经通过自定义的mycrawl
命令同时启动了爬虫文件first_spider、second_spider、third_spider