试想一下,前面做的实验和例子都只有一个spider。然而,现实的开发的爬虫肯定不止一个。既然这样,那么就会有如下几个问题:1、在同一个项目中怎么创建多个爬虫的呢?2、多个爬虫的时候是怎么将他们运行起来呢?

  说明:本文章是基于前面几篇文章和实验的基础上完成的。如果您错过了,或者有疑惑的地方可以在此查看:

  安装python爬虫scrapy踩过的那些坑和编程外的思考

  scrapy爬虫成长日记之创建工程-抽取数据-保存为json格式的数据

  scrapy爬虫成长日记之将抓取内容写入mysql数据库

  如何让你的scrapy爬虫不再被ban

  一、创建spider

  1、创建多个spider,scrapy genspider spidername domain

scrapy genspider CnblogsHomeSpider cnblogs.com

  通过上述命令创建了一个spider name为CnblogsHomeSpider的爬虫,start_urls为http://www.cnblogs.com/的爬虫

  2、查看项目下有几个爬虫scrapy list

[root@bogon cnblogs]# scrapy list
CnblogsHomeSpider
CnblogsSpider

  由此可以知道我的项目下有两个spider,一个名称叫CnblogsHomeSpider,另一个叫CnblogsSpider。

  更多关于scrapy命令可参考:http://doc.scrapy.org/en/latest/topics/commands.html

  二、让几个spider同时运行起来

  现在我们的项目有两个spider,那么现在我们怎样才能让两个spider同时运行起来呢?你可能会说写个shell脚本一个个调用,也可能会说写个python脚本一个个运行等。然而我在stackoverflow.com上看到。的确也有不上前辈是这么实现。然而官方文档是这么介绍的。

  1、Run Scrapy from a script

import scrapy
from scrapy.crawler import CrawlerProcessclass MySpider(scrapy.Spider):# Your spider definition
    ...process = CrawlerProcess({'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished

  这里主要通过scrapy.crawler.CrawlerProcess来实现在脚本里运行一个spider。更多的例子可以在此查看:https://github.com/scrapinghub/testspiders

  2、Running multiple spiders in the same process

  • 通过CrawlerProcess
import scrapy
from scrapy.crawler import CrawlerProcessclass MySpider1(scrapy.Spider):# Your first spider definition
    ...class MySpider2(scrapy.Spider):# Your second spider definition
    ...process = CrawlerProcess()
process.crawl(MySpider1)
process.crawl(MySpider2)
process.start() # the script will block here until all crawling jobs are finished

  • 通过CrawlerRunner
import scrapy
from twisted.internet import reactor
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_loggingclass MySpider1(scrapy.Spider):# Your first spider definition
    ...class MySpider2(scrapy.Spider):# Your second spider definition
    ...configure_logging()
runner = CrawlerRunner()
runner.crawl(MySpider1)
runner.crawl(MySpider2)
d = runner.join()
d.addBoth(lambda _: reactor.stop())reactor.run() # the script will block here until all crawling jobs are finished

  • 通过CrawlerRunner和链接(chaining) deferred来线性运行
from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_loggingclass MySpider1(scrapy.Spider):# Your first spider definition
    ...class MySpider2(scrapy.Spider):# Your second spider definition
    ...configure_logging()
runner = CrawlerRunner()@defer.inlineCallbacks
def crawl():yield runner.crawl(MySpider1)yield runner.crawl(MySpider2)reactor.stop()crawl()
reactor.run() # the script will block here until the last crawl call is finished

  这是官方文档提供的几种在script里面运行spider的方法。

  三、通过自定义scrapy命令的方式来运行

  创建项目命令可参考:http://doc.scrapy.org/en/master/topics/commands.html?highlight=commands_module#custom-project-commands

  1、创建commands目录

mkdir commands

  注意:commands和spiders目录是同级的

  2、在commands下面添加一个文件crawlall.py

  这里主要通过修改scrapy的crawl命令来完成同时执行spider的效果。crawl的源码可以在此查看:https://github.com/scrapy/scrapy/blob/master/scrapy/commands/crawl.py

from scrapy.commands import ScrapyCommand
from scrapy.crawler import CrawlerRunner
from scrapy.utils.conf import arglist_to_dictclass Command(ScrapyCommand):requires_project = Truedef syntax(self):  return '[options]'  def short_desc(self):  return 'Runs all of the spiders'  def add_options(self, parser):ScrapyCommand.add_options(self, parser)parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",help="set spider argument (may be repeated)")parser.add_option("-o", "--output", metavar="FILE",help="dump scraped items into FILE (use - for stdout)")parser.add_option("-t", "--output-format", metavar="FORMAT",help="format to use for dumping items with -o")def process_options(self, args, opts):ScrapyCommand.process_options(self, args, opts)try:opts.spargs = arglist_to_dict(opts.spargs)except ValueError:raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)def run(self, args, opts):#settings = get_project_settings()
spider_loader = self.crawler_process.spider_loaderfor spidername in args or spider_loader.list():print "*********cralall spidername************" + spidernameself.crawler_process.crawl(spidername, **opts.spargs)self.crawler_process.start()

  这里主要是用了self.crawler_process.spider_loader.list()方法获取项目下所有的spider,然后利用self.crawler_process.crawl运行spider

  3、commands命令下添加__init__.py文件

touch __init__.py

  注意:这一步一定不能省略。我就是因为这个问题折腾了一天。囧。。。就怪自己半路出家的吧。

  如果省略了会报这样一个异常

Traceback (most recent call last):File "/usr/local/bin/scrapy", line 9, in <module>load_entry_point('Scrapy==1.0.0rc2', 'console_scripts', 'scrapy')()File "/usr/local/lib/python2.7/site-packages/Scrapy-1.0.0rc2-py2.7.egg/scrapy/cmdline.py", line 122, in executecmds = _get_commands_dict(settings, inproject)File "/usr/local/lib/python2.7/site-packages/Scrapy-1.0.0rc2-py2.7.egg/scrapy/cmdline.py", line 50, in _get_commands_dictcmds.update(_get_commands_from_module(cmds_module, inproject))File "/usr/local/lib/python2.7/site-packages/Scrapy-1.0.0rc2-py2.7.egg/scrapy/cmdline.py", line 29, in _get_commands_from_modulefor cmd in _iter_command_classes(module):File "/usr/local/lib/python2.7/site-packages/Scrapy-1.0.0rc2-py2.7.egg/scrapy/cmdline.py", line 20, in _iter_command_classesfor module in walk_modules(module_name):File "/usr/local/lib/python2.7/site-packages/Scrapy-1.0.0rc2-py2.7.egg/scrapy/utils/misc.py", line 63, in walk_modulesmod = import_module(path)File "/usr/local/lib/python2.7/importlib/__init__.py", line 37, in import_module__import__(name)
ImportError: No module named commands

  一开始怎么找都找不到原因在哪。耗了我一整天,后来到http://stackoverflow.com/上得到了网友的帮助。再次感谢万能的互联网,要是没有那道墙该是多么的美好呀!扯远了,继续回来。

  4、settings.py目录下创建setup.py(这一步去掉也没影响,不知道官网帮助文档这么写有什么具体的意义。

from setuptools import setup, find_packagessetup(name='scrapy-mymodule',entry_points={'scrapy.commands': ['crawlall=cnblogs.commands:crawlall',],},)

  这个文件的含义是定义了一个crawlall命令,cnblogs.commands为命令文件目录,crawlall为命令名。

  5. 在settings.py中添加配置:

COMMANDS_MODULE = 'cnblogs.commands'

  6. 运行命令scrapy crawlall

  最后源码更新至此:https://github.com/jackgitgz/CnblogsSpider

同时运行多个scrapy爬虫的几种方法(自定义scrapy项目命令)相关推荐

  1. python爬虫十二种方法_Python爬虫的N种姿势

    问题的由来 前几天,在微信公众号(Python爬虫及算法)上有个人问了笔者一个问题,如何利用爬虫来实现如下的需求,需要爬取的网页如下(网址为:https://www.wikidata.org/w/in ...

  2. 【转】爬虫的几种方法的效率比较

    该文非原创文字,文字转载至  jclian91  链接:https://www.cnblogs.com/jclian91/p/9799697.html 问题的由来   前几天,在微信公众号(Pytho ...

  3. 如何提高加速运行Mac电脑系统缓慢的5种方法教程

    提高运行缓慢的Mac速度的5种方法 你曾经强大的Mac是不是一天比一天运行的越来越慢?听起来你需要(Mac)速度. 放心,你不是一个人.所有Mac机主迟早都会经历这种情况.随着岁月的流逝,他们曾经以光 ...

  4. python爬虫:两种方法模拟登录博客园

    第一方法用第三方库(requests):参考http://www.mamicode.com/info-detail-1839685.html 源代码分析 博客园的登录页面非常简单,查看网页源代码,可以 ...

  5. 屏蔽百度蜘蛛或某一爬虫的四种方法

    今天打开自己的网站发现很卡,但是检查网站的访问量并不高,登陆服务器发现流量很高,于是查看访问日志,发现网站日志中开头的某一ip段大量频繁访问,来自一个叫Bytespider的爬虫,就在网上查找方法想屏 ...

  6. python爬虫如何模仿登录_python爬虫:两种方法模拟登录博客园

    第一方法用第三方库(requests):参考http://www.mamicode.com/info-detail-1839685.html 源代码分析 博客园的登录页面非常简单,查看网页源代码,可以 ...

  7. abaqus高版本的cae文件无法在低版本运行怎么办?别急,两种方法帮你解决问题!

    方法一: 低版本和高版本的cae文件虽然不兼容,但inp文件兼容,只需高版本job模块 write input即可生成inp文件,在低版本中,点击File-import-model,选择inp文件格式 ...

  8. python爬虫有几种方法_基于Python爬虫的几种方法,python

    一  requests,json格式数据 #1.获取链接 url = #2.获取响应 response = requests.get(url) response = response.content. ...

  9. python爬虫有几种方法_python爬虫-----Python访问http的几种方式

    爬取页面数据,我们需要访问页面,发送http请求,以下内容就是Python发送请求的几种简单方式: 会使用到的库 urllib requests 1.urlopen import urllib.req ...

最新文章

  1. 采用Filter的方法解决Servlet的编码问题
  2. 翻身的废鱼——论PHP从入门到放弃需要多久?15
  3. python 返回函数对象_返回函数
  4. 51nod 1118 机器人走方格 解题思路:动态规划 1119 机器人走方格 V2 解题思路:根据杨辉三角转化问题为组合数和求逆元问题
  5. 后端技术:Java程序员常用的11个API,你都知道吗?
  6. java二嗨租车项目_Java入门第二季6-1租车项目代码
  7. android上传图片文件至c 服务器,Android 史上最优雅的实现文件上传、下载及进度的监听...
  8. Codeforces Round #202 (Div. 1): D. Turtles(Lindström–Gessel–Viennot lemma定理+DP)
  9. Shell脚本中的分号使用
  10. C64+DSP资源手册笔记
  11. 求方程式ax2bxc0的根c语言,2019-03-09 C语言学习12-求ax^2+bx+c=0方程的根
  12. Word插入脚注后分节符自动变成分页符 解决办法
  13. 5G聚合路由器有哪些优势?能应用在哪些场景?
  14. 如何使用代理服务器上网
  15. 【最大公约数】欧几里得算法
  16. h5底部输入框被键盘遮挡_总结几个移动端H5软键盘的大坑【实践】
  17. 关于Python爬取热搜的另一种方法
  18. 数字电路3(逻辑函数的卡诺图化简法)
  19. 《Think Python 2e》作业实现(二): 变量、表达式和语句
  20. Web网页如何实现QQ好友,QQ空间,微博分享

热门文章

  1. freebsd用户密码文件
  2. Kotlin 1.3.30 发布,改进性能和引入新特性
  3. 拖拽的原生和jQuery写法
  4. iOS Public Beta 5值得关注的7个变化
  5. 陌陌股价过山车背后隐藏了什么?
  6. 微服务架构——不是免费的午餐
  7. C/C++:多个.cpp文件包括同一个.h头文件定义方法
  8. ubuntu系统安装FTP
  9. 39条常见的Linux系统简单面试题
  10. 图文并茂的生产者消费者应用实例demo