同時運行多個scrapy爬蟲的幾種方法(自定義scrapy項目命令)

試想一下,前面做的實驗和例子都只有一個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 listCnblogsHomeSpider

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 scrapyfrom 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 scrapyfrom 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 scrapyfrom twisted.internet import reactorfrom scrapy.crawler import CrawlerRunnerfrom 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, deferfrom scrapy.crawler import CrawlerRunnerfrom 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.inlineCallbacksdef 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 CrawlerRunnerfrom scrapy.utils.conf import arglist_to_dictclass Command(ScrapyCommand):


? ? requires_project = True


? ? def 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_loader

? ? ? ? for spidername in args or spider_loader.list():

? ? ? ? ? ? print "*********cralall spidername************" + spidername

? ? ? ? ? ? self.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

? ? 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 execute

? ? cmds = _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_dict

? ? cmds.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_module

? ? for 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_classes

? ? for 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_modules

? ? mod = 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_packages

setup(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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容