使用scrapy_redis進行kuku漫畫全站爬取

思路

雖然scrapy支持多線程型型,但是單機scrapy也是有性能瓶頸的衙耕。使用scrapy-redis可以將scrapy改造成分布式的爬蟲架構(gòu)吩愧。

改造的原理是什么寇甸?

對于原版的scrapy缤沦,scrapy-redis修改了四個部分:調(diào)度器(Scheduler)虎韵、去重(Dupefilter)、管道(Pipeline)缸废、抓取器(Spider)包蓝。其核心是使用了redis代替了原本的queue,因為redis可以作為一個消息隊列企量,這樣多個爬蟲實例就可以通過共享消息隊列來實現(xiàn)分布式了测萎。

要實現(xiàn)分布式主要要解決的問題無非就是幾個:

  • 任務(wù)分發(fā),讓每個實例知道自己要做什么届巩。
  • 共享消息隊列硅瞧,不能出現(xiàn)重復(fù)爬取的情況。

這里Scheduler就是用來分發(fā)任務(wù)的恕汇;如果配置了去重腕唧,Dupefilter會負責(zé)維護一個集合,包含抓取過的url瘾英,避免重復(fù)抓仍娼印;Pipeline可以是自己寫的缺谴,也可以使用RedisPipeline將結(jié)果存儲在redis中但惶;最后Spider中需要實現(xiàn)具體爬蟲功能的部分,也是寫代碼的地方。

如果一切順利膀曾,你可以看到Redis中會出現(xiàn)三個序列:

scrapy_redis_db11.jpg

Redis中的key都是按照spidername:word的形式來命名的片拍,其中Dupefiler用來去重,需要合適的配置項妓肢。Requests包含了所有爬取的序列捌省,是所有各個爬蟲節(jié)點的任務(wù)來源;同時所有在爬取過程中yield出的新request都會被放入這個序列碉钠。最后如果你在配置項中使用了RedisPipeline纲缓,Spider返回的結(jié)果會被存儲在Items中。

除了這三個序列喊废,有時候會有一個名為start_urls序列祝高。如果你的爬蟲只寫了處理一個URL時的代碼,但是沒有其實URL污筷,也就是說爬蟲不知道從哪個url開始入手(有了第一個URL之后就會像蛛網(wǎng)一樣衍生出更多的URL)工闺。這時候你會需要用到redis-cli(redis的客戶端程序)來手動向redis中添加一條url:

redis-cli -h redis_addr -p redis_port -n redis_db# lpush spidername:start_urls CustomURL

這個項目里我把start_urls直接寫在代碼里了。

怎么部署這個分布式爬蟲瓣蛀?

scrapy本身支持并發(fā)和異步IO陆蟆,通過修改其配置項CONCURRENT_REQUESTS來實現(xiàn),默認為16惋增。因為GIL的存在叠殷,如果配置合理,此時的爬蟲會占滿你一個CPU核心诈皿;通過手動執(zhí)行N個爬蟲實例(scrapy crawl comicCrawler)林束,N一般是你的CPU核心數(shù),你可以充分發(fā)揮出一臺機器的性能稽亏。同樣壶冒,在其他機器上,你可以執(zhí)行相同的操作截歉,所有的爬蟲實例都共享一個redis數(shù)據(jù)庫哼勇。通過這種多進程+多線程的模式诵闭,理論上可以最大限度地發(fā)揮機器的能力引镊。

具體怎么做桂塞?

這里只包含了從scrapy轉(zhuǎn)scrapy-redis需要修改的地方。

修改Setting.py

在官網(wǎng)上提供了一個scrapy-redis的完整配置文件凉逛,可以按需修改性宏,一般來說,有幾個是必須的状飞,你需要在原本的Setting.py的基礎(chǔ)上毫胜,增加:

SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER_PERSIST = True
REDIS_HOST = '34.229.250.31'
REDIS_PORT = 6379
REDIS_PARAMS = {
    'db': 11
}
LOG_LEVEL = 'DEBUG'

幾個比較重要參數(shù)是:

  • SCHEDULER`是核心部分书斜,scrapy-redis重寫了調(diào)度器用于管理分布式架構(gòu)。
  • DUPEFILTER_CLASS用用于去重酵使。
  • SCHEDULER_PERSIST允許配置是否可以暫停\繼續(xù)爬蟲荐吉,互有利弊。
  • SCHEDULER_QUEUE_CLASS是隊列的類型口渔,有三種:PriorityQueue(默認), FifoQueueLifoQueue样屠。
  • REDIS系列:Redis有幾種配置方法,可以使用REDIS_HOST+REDIS_PORT組合缺脉,也可使用REDIS_URL痪欲,也可以通過REDIS_PARAMS字典對具體的某個參數(shù)做調(diào)整,比如說攻礼,例子里业踢,我選擇使用redis數(shù)據(jù)庫中的第11個實例,避免與其他爬蟲沖突礁扮。
  • 其他的一般保持默認即可知举。

除了新增的幾個配置項,如果你選擇將最終的結(jié)果存入redis太伊,你需要向ITEM_PIPELINES中添加scrapy_redis.pipelines.RedisPipeline管道雇锡。

ITEM_PIPELINES = {
    'comicspider.pipelines.ComicspiderPipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400
}

修改spider文件

所有涉及到的spider文件都需要修改,scarpy的spider類一般繼承于scrapy.Spider倦畅,這里要調(diào)整為scrapy_redis.spiders遮糖。然后,沒了叠赐。

這里沒了是我這個例子中,不需要修改其他代碼了屡江。但是每個人可能寫的spider的結(jié)構(gòu)不一樣芭概,因此調(diào)整起來可能還有一點出入。

比如說:

  • 在我的例子中惩嘉,我沒有使用scrapy的Rules部件罢洲,因此在多頁面爬取的時候,我需要為每一類請求都指定好合適的callback文黎。你可以通過配置好Rules惹苗,它可以通過匹配請求的URL,然后給每一類URL綁定相應(yīng)的回調(diào)函數(shù)耸峭。
  • 如果你沒有在代碼中配置start_urls桩蓉,你需要指定一個redis的key值用來之后向其中推送請求,redis_key='comicCrawler:start_urls'劳闹。

代碼和效果

代碼我放在GitHub上了院究,我的筆記本是八核的洽瞬,然后再加一個云主機,我一共起了9個實例业汰,每個實例的并發(fā)數(shù)是16伙窃。最后跑出來,大概一個小時可以抓到27W結(jié)果样漆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末为障,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子放祟,更是在濱河造成了極大的恐慌产场,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舞竿,死亡現(xiàn)場離奇詭異京景,居然都是意外死亡,警方通過查閱死者的電腦和手機骗奖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門确徙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人执桌,你說我怎么就攤上這事鄙皇。” “怎么了仰挣?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵伴逸,是天一觀的道長。 經(jīng)常有香客問我膘壶,道長错蝴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任颓芭,我火速辦了婚禮顷锰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亡问。我一直安慰自己官紫,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布州藕。 她就那樣靜靜地躺著束世,像睡著了一般。 火紅的嫁衣襯著肌膚如雪床玻。 梳的紋絲不亂的頭發(fā)上毁涉,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音笨枯,去河邊找鬼薪丁。 笑死遇西,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的严嗜。 我是一名探鬼主播粱檀,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼漫玄!你這毒婦竟也來了茄蚯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤睦优,失蹤者是張志新(化名)和其女友劉穎渗常,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汗盘,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡皱碘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了隐孽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癌椿。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖菱阵,靈堂內(nèi)的尸體忽然破棺而出踢俄,到底是詐尸還是另有隱情,我是刑警寧澤晴及,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布都办,位于F島的核電站,受9級特大地震影響虑稼,放射性物質(zhì)發(fā)生泄漏琳钉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一动雹、第九天 我趴在偏房一處隱蔽的房頂上張望槽卫。 院中可真熱鬧,春花似錦胰蝠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至查剖,卻和暖如春钾虐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笋庄。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工效扫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留倔监,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓菌仁,卻偏偏與公主長得像浩习,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子济丘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容