亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

近在工作中寫(xiě)了很多 scrapy_redis 分布式爬蟲(chóng),但是回想 scrapy 與 scrapy_redis 兩者區(qū)別的時(shí)候,竟然,思維只是局限在了應(yīng)用方面,于是乎,搜索了很多相關(guān)文章介紹,這才搞懂內(nèi)部實(shí)現(xiàn)的原理。

首先我們從整體上來(lái)講

scrapy是一個(gè)Python爬蟲(chóng)框架,爬取效率極高,具有高度定制性,但是不支持分布式。而scrapy-redis一套基于redis數(shù)據(jù)庫(kù)、運(yùn)行在scrapy框架之上的組件,可以讓scrapy支持分布式策略,Slaver端共享Master端redis數(shù)據(jù)庫(kù)里的item隊(duì)列、請(qǐng)求隊(duì)列和請(qǐng)求指紋集合。而為什么選擇redis數(shù)據(jù)庫(kù),是因?yàn)閞edis支持主從同步,而且數(shù)據(jù)都是緩存在內(nèi)存中的,所以基于redis的分布式爬蟲(chóng),對(duì)請(qǐng)求和數(shù)據(jù)的高頻讀取效率非常高。

有一篇文章是這么說(shuō)的: scrapy-redis 與 Scrapy 的關(guān)系就像電腦與固態(tài)硬盤(pán)一樣,是電腦中的一個(gè)插件,能讓電腦更快的運(yùn)行。

淺析scrapy與scrapy_redis區(qū)別

 

Scrapy 是一個(gè)爬蟲(chóng)框架, scrapy-redis 則是這個(gè)框架上可以選擇的插件,它可以讓爬蟲(chóng)跑的更快。

說(shuō)的一點(diǎn)都對(duì), Scrapy 是一個(gè)通用的爬蟲(chóng)框架, scrapy-redis 則是這個(gè)框架上可以選擇的插件,為了更方便地實(shí)現(xiàn)Scrapy分布式爬取,而提供了一些以redis為基礎(chǔ)的組件(僅有組件),它可以讓爬蟲(chóng)跑的更快。

然后介紹 scrapy 框架的運(yùn)行流程及原理

scrapy作為一款優(yōu)秀的爬蟲(chóng)框架,在爬蟲(chóng)方面有這眾多的優(yōu)點(diǎn)。能快速、高層次的屏幕抓取和web抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結(jié)構(gòu)化的數(shù)據(jù)。

淺析scrapy與scrapy_redis區(qū)別

 

為了方便理解,我找到了一張這樣的圖片:

淺析scrapy與scrapy_redis區(qū)別

 

解釋說(shuō)明:

1、從優(yōu)先級(jí)隊(duì)列中獲取request對(duì)象,交給engine

2、engine將request對(duì)象交給下載器下載,期間會(huì)通過(guò)downloadmiddleware的process_request方法

3、下載器完成下載,獲得response對(duì)象,將該對(duì)象交給engine,期間會(huì)經(jīng)過(guò)downloadmiddleware的process_response( )方法

4、engine將獲得的response對(duì)象交給spider進(jìn)行解析,期間會(huì)經(jīng)過(guò)spidermiddleware的process_spider_input()的方法

5、spider解析下載器下下來(lái)的response,返回item或是links(url)

6、item或者link經(jīng)過(guò)spidermiddleware的process_spider_out( )方法,交給engine

7、engine將item交給item pipeline ,將links交給調(diào)度器

8、在調(diào)度器中,先將requests對(duì)象利用scrapy內(nèi)置的指紋函數(shù)生成一個(gè)指紋

9、如果requests對(duì)象中的don't filter參數(shù)設(shè)置為False,并且該requests對(duì)象的指紋不在信息指紋的隊(duì)列中,那么就把該request對(duì)象放到優(yōu)先級(jí)隊(duì)列中

淺析scrapy與scrapy_redis區(qū)別

 

循環(huán)以上操作

中間件主要存在兩個(gè)地方,從圖片當(dāng)中我們可以看到:

spider 與 engine 之間(爬蟲(chóng)中間件):

介于Scrapy引擎和爬蟲(chóng)之間的框架,主要工作是處理爬蟲(chóng)的響應(yīng)輸入和請(qǐng)求輸出

download 與 engine 之間(下載器中間件) :

位于Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請(qǐng)求及響應(yīng)

借此機(jī)會(huì),我們結(jié)合程序,解析一下框架中的 middleware.py :

1. Spider Middleware有以下幾個(gè)函數(shù)被管理:

- process_spider_input 接收一個(gè)response對(duì)象并處理,

位置是Downloader-->process_spider_input-->Spiders(Downloader和Spiders是scrapy官方結(jié)構(gòu)圖中的組件)

- process_spider_exception spider出現(xiàn)的異常時(shí)被調(diào)用

- process_spider_output 當(dāng)Spider處理response返回result時(shí),該方法被調(diào)用

- process_start_requests 當(dāng)spider發(fā)出請(qǐng)求時(shí),被調(diào)用

2. Downloader Middleware有以下幾個(gè)函數(shù)被管理

- process_request request通過(guò)下載中間件時(shí),該方法被調(diào)用,這里可以設(shè)置代理,設(shè)置request.meta['proxy'] 就行

- process_response 下載結(jié)果經(jīng)過(guò)中間件時(shí)被此方法處理

- process_exception 下載過(guò)程中出現(xiàn)異常時(shí)被調(diào)用

個(gè)人理解scrapy的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):scrapy 是異步的, 寫(xiě)middleware,方便寫(xiě)一些統(tǒng)一的過(guò)濾器

缺點(diǎn):基于python的爬蟲(chóng)框架,擴(kuò)展性比較差, 基于twisted框架,運(yùn)行中的exception是不會(huì)干掉reactor,并且異步框架出錯(cuò)后是不會(huì)停掉其他任務(wù)的,數(shù)據(jù)出錯(cuò)后難以察覺(jué)。

scrapy_redis分布式爬蟲(chóng)

最后回到我們這篇文章的重點(diǎn)(敲黑板...)

Scrapy-redis提供了下面四種組件(components):(四種組件意味著這四個(gè)模塊都要做相應(yīng)的修改)

Scheduler:

Scrapy改造了python本來(lái)的collection.deque(雙向隊(duì)列)形成了自己的Scrapy queue,但是Scrapy多個(gè)spider不能共享待爬取隊(duì)列Scrapy queue, 即Scrapy本身不支持爬蟲(chóng)分布式,scrapy-redis 的解決是把這個(gè)Scrapy queue換成redis數(shù)據(jù)庫(kù)(也是指redis隊(duì)列),從同一個(gè)redis-server存放要爬取的request,便能讓多個(gè)spider去同一個(gè)數(shù)據(jù)庫(kù)里讀取。

淺析scrapy與scrapy_redis區(qū)別

 

Scrapy中跟“待爬隊(duì)列”直接相關(guān)的就是調(diào)度器Scheduler,它負(fù)責(zé)對(duì)新的request進(jìn)行入列操作(加入Scrapy queue),取出下一個(gè)要爬取的request(從Scrapy queue中取出)等操作。它把待爬隊(duì)列按照優(yōu)先級(jí)建立了一個(gè)字典結(jié)構(gòu),然后根據(jù)request中的優(yōu)先級(jí),來(lái)決定該入哪個(gè)隊(duì)列,出列時(shí)則按優(yōu)先級(jí)較小的優(yōu)先出列。為了管理這個(gè)比較高級(jí)的隊(duì)列字典,Scheduler需要提供一系列的方法。但是原來(lái)的Scheduler已經(jīng)無(wú)法使用,所以使用Scrapy-redis的scheduler組件。

Duplication Filter:

Scrapy中用集合實(shí)現(xiàn)這個(gè)request去重功能,Scrapy中把已經(jīng)發(fā)送的request指紋放入到一個(gè)集合中,把下一個(gè)request的指紋拿到集合中比對(duì),如果該指紋存在于集合中,說(shuō)明這個(gè)request發(fā)送過(guò)了,如果沒(méi)有則繼續(xù)操作。

在scrapy-redis中去重是由Duplication Filter組件來(lái)實(shí)現(xiàn)的,它通過(guò)redis的set 不重復(fù)的特性,巧妙的實(shí)現(xiàn)了Duplication Filter去重。scrapy-redis調(diào)度器從引擎接受request,將request的指紋存?redis的set檢查是否重復(fù),并將不重復(fù)的request push寫(xiě)?redis的 request queue。

引擎請(qǐng)求request(Spider發(fā)出的)時(shí),調(diào)度器從redis的request queue隊(duì)列?里根據(jù)優(yōu)先級(jí)pop 出?個(gè)request 返回給引擎,引擎將此request發(fā)給spider處理。

Item Pipeline:

引擎將(Spider返回的)爬取到的Item給Item Pipeline,scrapy-redis 的Item Pipeline將爬取到的 Item 存?redis的 items queue。

修改過(guò)Item Pipeline可以很方便的根據(jù) key 從 items queue 提取item,從?實(shí)現(xiàn)items processes集 群。

Base Spider:

不在使用scrapy原有的Spider類,重寫(xiě)的RedisSpider繼承了Spider和RedisMixin這兩個(gè)類,RedisMixin是用來(lái)從redis讀取url的類。

當(dāng)我們生成一個(gè)Spider繼承RedisSpider時(shí),調(diào)用setup_redis函數(shù),這個(gè)函數(shù)會(huì)去連接redis數(shù)據(jù)庫(kù),然后會(huì)設(shè)置signals(信號(hào)):

一個(gè)是當(dāng)spider空閑時(shí)候的signal,會(huì)調(diào)用spider_idle函數(shù),這個(gè)函數(shù)調(diào)用schedule_next_request函數(shù),保證spider是一直活著的狀態(tài),并且拋出DontCloseSpider異常。

一個(gè)是當(dāng)抓到一個(gè)item時(shí)的signal,會(huì)調(diào)用item_scraped函數(shù),這個(gè)函數(shù)會(huì)調(diào)用schedule_next_request函數(shù),獲取下一個(gè)request。

Scrapy-redis架構(gòu):

淺析scrapy與scrapy_redis區(qū)別

 

如上圖所示,我們可以發(fā)現(xiàn),scrapy-redis在scrapy的架構(gòu)上增加了redis,與scrapy相差無(wú)幾。本質(zhì)的區(qū)別就是,將scrapy的內(nèi)置的去重的隊(duì)列和待抓取的request隊(duì)列換成了redis的集合。就這一個(gè)小小的改動(dòng),就使得了scrapy-redis支持了分布式抓取。

Scrapy-Redis分布式策略:

假設(shè)有四臺(tái)電腦:windows 10、mac OS X、Ubuntu 16.04、centos 7.2,任意一臺(tái)電腦都可以作為 Master端 或 Slaver端,比如:

--Master端(核心服務(wù)器) :使用 Windows 10,搭建一個(gè)Redis數(shù)據(jù)庫(kù),不負(fù)責(zé)爬取,只負(fù)責(zé)url指紋判重、Request的分配,以及數(shù)據(jù)的存儲(chǔ)

--Slaver端(爬蟲(chóng)程序執(zhí)行端) :使用 Mac OS X 、Ubuntu 16.04、CentOS 7.2,負(fù)責(zé)執(zhí)行爬蟲(chóng)程序,運(yùn)行過(guò)程中提交新的Request給Master

淺析scrapy與scrapy_redis區(qū)別

 

首先Slaver端從Master端拿任務(wù)(Request、url)進(jìn)行數(shù)據(jù)抓取,Slaver抓取數(shù)據(jù)的同時(shí),產(chǎn)生新任務(wù)的Request便提交給 Master 處理;

Master端只有一個(gè)Redis數(shù)據(jù)庫(kù),負(fù)責(zé)將未處理的Request去重和任務(wù)分配,將處理后的Request加入待爬隊(duì)列,并且存儲(chǔ)爬取的數(shù)據(jù)。

明白了原理之后我們就要入手程序了

Scrapy-Redis默認(rèn)使用的就是這種策略,我們實(shí)現(xiàn)起來(lái)很簡(jiǎn)單,因?yàn)槿蝿?wù)調(diào)度等工作Scrapy-Redis都已經(jīng)幫我們做好了,我們只需要繼承RedisSpider、指定redis_key就行了。

將 scrapy 變成 scrapy-redis 的過(guò)程(前提是pip install scrapy-redis)

最簡(jiǎn)單的方式是使用 redis 替換機(jī)器內(nèi)存,你只需要在 settings.py 中加上三代碼,就能讓你的爬蟲(chóng)變?yōu)榉植际健?/p>淺析scrapy與scrapy_redis區(qū)別

 

如果你現(xiàn)在運(yùn)行你的爬蟲(chóng),你可以在redis中看到出現(xiàn)了這兩個(gè)key:

淺析scrapy與scrapy_redis區(qū)別

 

格式是set,即不會(huì)有重復(fù)數(shù)據(jù)。前者就是redis的去重隊(duì)列,對(duì)應(yīng) DUPEFILTER_CLASS ,后者是redis的請(qǐng)求調(diào)度,把里面的請(qǐng)求分發(fā)給爬蟲(chóng),對(duì)應(yīng) SCHEDULER 。(里面的數(shù)據(jù)不會(huì)自動(dòng)刪除,如果你第二次跑,需要提前清空里面的數(shù)據(jù))

缺點(diǎn)是,Scrapy-Redis調(diào)度的任務(wù)是Request對(duì)象,里面信息量比較大(不僅包含url,還有callback函數(shù)、headers等信息),可能導(dǎo)致的結(jié)果就是會(huì)降低爬蟲(chóng)速度、而且會(huì)占用Redis大量的存儲(chǔ)空間,所以如果要保證效率,那么就需要一定硬件水平。

分享到:
標(biāo)簽:scrapy
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定