scrapy-redis分布式爬虫启动为什么会等待 scrapy redis中在爬取分页网站怎么重启爬虫之后在下...
\u600e\u4e48\u7528scrapy-redis\u5199\u5206\u5e03\u5f0f\u722c\u866bRedis \u662f\u5b8c\u5168\u5f00\u6e90\u514d\u8d39\u7684\uff0c\u9075\u5b88BSD\u534f\u8bae\uff0c\u662f\u4e00\u4e2a\u9ad8\u6027\u80fd\u7684key-value\u6570\u636e\u5e93\u3002\u652f\u6301\u6570\u636e\u7684\u6301\u4e45\u5316\uff0c\u53ef\u4ee5\u5c06\u5185\u5b58\u4e2d\u7684\u6570\u636e\u4fdd\u5b58\u5728\u78c1\u76d8\u4e2d\uff0c\u91cd\u542f\u7684\u65f6\u5019\u53ef\u4ee5\u518d\u6b21\u52a0\u8f7d\u8fdb\u884c\u4f7f\u7528\u3002 \u8fd8\u63d0\u4f9blist\uff0cset\uff0czset\uff0chash\u7b49\u6570\u636e\u7ed3\u6784\u7684\u5b58\u50a8\u3002
\u5728github\u4e0a\u7684scrapy-redis\u6587\u6863\u4e0a\u5c31\u6709\u914d\u7f6e\u542f\u52a8/\u6682\u505c\u7684\u8bf4\u660e
# Don't cleanup redis queues, allows to pause/resume crawls.
#SCHEDULER_PERSIST = True
scrapy-redis所实现的两种分布式:爬虫分布式以及item处理分布式。分别是由模块scheduler和模块pipelines实现。
一、Scrapy-redis各个组件介绍
(I) connection.py
负责根据setting中配置实例化redis连接。被dupefilter和scheduler调用,总之涉及到redis存取的都要使用到这个模块。
(II) dupefilter.py
负责执行requst的去重,实现的很有技巧性,使用redis的set数据结构。但是注意scheduler并不使用其中用于在这个模块中实现的dupefilter键做request的调度,而是使用queue.py模块中实现的queue。
当request不重复时,将其存入到queue中,调度时将其弹出。
(III)queue.py
其作用如II所述,但是这里实现了三种方式的queue:
FIFO的SpiderQueue,SpiderPriorityQueue,以及LIFI的SpiderStack。默认使用的是第二中,这也就是出现之前文章中所分析情况的原因(链接)。
(IV)pipelines.py
这是是用来实现分布式处理的作用。它将Item存储在redis中以实现分布式处理。
另外可以发现,同样是编写pipelines,在这里的编码实现不同于文章(链接:)中所分析的情况,由于在这里需要读取配置,所以就用到了from_crawler()函数。
(V)scheduler.py
此扩展是对scrapy中自带的scheduler的替代(在settings的SCHEDULER变量中指出),正是利用此扩展实现crawler的分布式调度。其利用的数据结构来自于queue中实现的数据结构。
scrapy-redis所实现的两种分布式:爬虫分布式以及item处理分布式就是由模块scheduler和模块pipelines实现。上述其它模块作为为二者辅助的功能模块。
(VI)spider.py
设计的这个spider从redis中读取要爬的url,然后执行爬取,若爬取过程中返回更多的url,那么继续进行直至所有的request完成。之后继续从redis中读取url,循环这个过程。
二、组件之间的关系
三、scrapy-redis实例分析
(1) spiders/ ebay_redis.py
classEbayCrawler(RedisMixin,CrawlSpider):
"""Spiderthat reads urls from redis queue (mycrawler:start_urls)."""
name = 'ebay_redis'
redis_key = ' ebay_redis:start_urls'
rules = (
# follow all links
# Rule(SgmlLinkExtractor(),callback='parse_page', follow=True),
Rule(sle(allow=('[^\s]+/itm/', )), callback='parse_item'),
)
#该方法是最关键的方法,该方法名以下划线开头,建立了和redis的关系
def _set_crawler(self, crawler):
CrawlSpider._set_crawler(self, crawler)
RedisMixin.setup_redis(self)
# 解析sku页面
defparse_item(self,response):
sel =Selector(response)
base_url =get_base_url(response)
item = EbayphoneItem()
print base_url
item['baseurl'] =[base_url]
item['goodsname'] =sel.xpath("//h1[@id='itemTitle']/text()").extract()
return item
该类继承了RedisMixin(scrapy_redis/spiders.py中的一个类)和CrawlSpider,加载配置文件的各项,建立和redis的关联,同时进行抓取后的解析。关键方法为_set_crawler(self, crawler),关键属性是redis_key,该key如果没有初始化则默认为spider.name:start_urls
_set_crawler()方法是如何被调用的:
scrapy/crawl.py/Crawler: crawl() ->
scrapy/crawl.py/Crawler:_create_spider () ->
CrawlSpider:from_crawler() –>
scrapy/spiders/Spider: from_crawler() ->
ebay_redis.py :_set_crawler()
(2) setting.py
SPIDER_MODULES= ['example.spiders']
NEWSPIDER_MODULE= 'example.spiders'
ITEM_PIPELINES = {
'example.pipelines.ExamplePipeline':300,
#通过配置下面该项RedisPipeline'会将item写入key为
#spider.name:items的redis的list中,供后面的分布式处理item
'scrapy_redis.pipelines.RedisPipeline':400,
}
SCHEDULER= "scrapy_redis.scheduler.Scheduler"
#不清理redisqueues, 允许暂停或重启crawls
SCHEDULER_PERSIST= True
SCHEDULER_QUEUE_CLASS= 'scrapy_redis.queue.SpiderPriorityQueue'
#该项仅对queueclass is SpiderQueue or SpiderStack生效,阻止spider被关闭的最大空闲时间
SCHEDULER_IDLE_BEFORE_CLOSE= 10
#连接redis使用
REDIS_HOST = '123.56.184.53'
REDIS_PORT= 6379
(3) process_items.py:
defmain():
pool =redis.ConnectionPool(host='123.56.184.53', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
while True:
# process queue as FIFO, change `blpop`to `brpop` to process as LIFO
source, data =r.blpop(["ebay_redis:items"])
item = json.loads(data)
try:
print u"Processing: %(name)s<%(link)s>" % item
except KeyError:
print u"Error procesing:%r" % item
if__name__ == '__main__':
main()
该模块是从redis对应的list中取出item,进行处理,可以运行多个进程分布式处理items
(4)执行过程如下:
首先在redis服务器端打开redis服务:
./redis-server
其次执行
./redis-cli lpush ebaycrawler:start_urls http://www.ebay.com/sch/Cell-Phones-Smartphones-/9355/i.html
然后运行爬虫:
scrapy runspiderebay_redis.py
可以执行多个爬虫,同时对ebay_redis:start_urls中的url进行分布式爬取,爬取后的结果都存入了ebay_redis:items的list中,供后续再次处理
最后可以查看items队列中的内容
./redis-cli llen ebay_redis:items 可以看到该items中总的个数
绛旓細scrapy鍜scrapy-redis涓嶅簲璇ヨ璁哄尯鍒俿crapy 鏄竴涓氱敤鐨勭埇铏鏋讹紝鍏跺姛鑳芥瘮杈冨畬鍠勶紝鍙互甯綘杩呴熺殑鍐欎竴涓畝鍗曠埇铏紝骞朵笖璺戣捣鏉ャ俿crapy-redis鏄负浜嗘洿鏂逛究鍦板疄鐜scrapy鍒嗗竷寮鐖彇锛岃屾彁渚涗簡涓浜涗互redis涓哄熀纭鐨勭粍浠讹紙娉ㄦ剰锛宻crapy-redis鍙槸涓浜涚粍浠讹紝鑰屼笉鏄竴涓畬鏁寸殑妗嗘灦锛夈備綘鍙互杩欎箞璁や负锛宻crapy鏄竴宸...
绛旓細scrapy-redis鎵瀹炵幇鐨勪袱绉鍒嗗竷寮锛氱埇铏垎甯冨紡浠ュ強item澶勭悊鍒嗗竷寮忓氨鏄敱妯″潡scheduler鍜屾ā鍧梡ipelines瀹炵幇銆備笂杩板叾瀹冩ā鍧椾綔涓轰负浜岃呰緟鍔╃殑鍔熻兘妯″潡銆傦紙VI锛塻pider.py 璁捐鐨勮繖涓猻pider浠巖edis涓鍙栬鐖殑url,鐒跺悗鎵ц鐖彇锛岃嫢鐖彇杩囩▼涓繑鍥炴洿澶氱殑url锛岄偅涔堢户缁繘琛岀洿鑷虫墍鏈夌殑request瀹屾垚銆備箣鍚庣户缁粠redis涓鍙杣rl...
绛旓細鍦Scrapy涓锛屾垜浠疄闄呮槸鎶婄埇鍙栭槦鍒椾繚瀛樺埌鏈湴锛岀浜屾鐖彇鐩存帴璇诲彇骞舵仮澶嶉槦鍒楀嵆鍙傞偅涔堝湪鍒嗗竷寮鏋舵瀯涓垜浠繕鐢ㄦ媴蹇冭繖涓棶棰樺悧锛熶笉闇瑕併傚洜涓虹埇鍙栭槦鍒楁湰韬氨鏄敤鏁版嵁搴撲繚瀛樼殑锛屽鏋滅埇铏腑鏂簡锛屾暟鎹簱涓殑Request渚濈劧鏄瓨鍦ㄧ殑锛屼笅娆″惎鍔ㄥ氨浼氭帴鐫涓婃涓柇鐨勫湴鏂圭户缁埇鍙栥傛墍浠ワ紝褰Redis鐨闃熷垪涓虹┖鏃讹紝鐖櫕浼...
绛旓細绗9绔scrapy-redis鍒嗗竷寮鐖櫕Scrapy-redis鍒嗗竷寮鐖櫕鐨勪娇鐢ㄤ互鍙妔crapy-redis鐨勫垎甯冨紡鐖櫕鐨勬簮鐮佸垎鏋愶紝璁╁ぇ瀹跺彲浠ユ牴鎹嚜宸辩殑闇姹傛潵淇敼婧愮爜浠ユ弧瓒宠嚜宸辩殑闇姹傘傛渶鍚庝篃浼氳瑙e浣曞皢bloomfilter闆嗘垚鍒皊crapy-redis涓傜10绔犳悳绱㈠紩鎿庣殑浣跨敤鏈珷灏嗚瑙g殑瀹夎鍜屼娇鐢紝灏嗚瑙g殑鍩烘湰姒傚康鐨勪粙缁嶄互鍙奱pi鐨勪娇鐢ㄣ傛湰绔犱篃浼氳瑙...
绛旓細涓昏瀛︿範鐨勬湁Python璇█鍩虹銆丮ySQL銆丩inux銆乄eb缂栫▼鍩虹銆丏jango妗嗘灦銆丗lask妗嗘灦銆乀ornado妗嗘灦銆佹暟鎹埇鍙栥侀獙璇佺爜鐮磋В銆佹暟鎹殑瀛樺偍銆佺牬瑙e姞瀵嗐Scrapy-Redis鍒嗗竷寮銆丗iddler宸ュ叿銆佸绾跨▼鐖櫕銆丼crapy妗嗘灦銆佷唬鐞嗘睜鍜孋ookie姹犮佹繁搴﹀涔犳鏋躲佹満鍣ㄥ涔犮佹暟鎹垎鏋愩佹繁搴﹀涔犮佹繁搴﹀涔犳鏋-Pytorch绛 鍋歱ython寮鍙戦渶瑕...
绛旓細Scrapy鑻辨枃鎰忔濇槸鍒摝 琚敤鏉ュ懡鍚嶇埇铏晫鐭ュ悕鐨勬鏋躲備娇鐢ㄨ繖涓鏋跺彲浠ヨ交鏄撳疄鐜板父瑙勭綉椤甸噰闆嗐備篃鏀寔澶у瀷鏋舵瀯銆傚崌绾у悗redis鏇存槸鏀寔鍒嗗竷寮銆傚埄鐢╯crapyd鏇存槸鍙互鍙戝竷鏈嶅姟銆備粠浜嬬埇铏柟鍚戝繀瀛︼紒
绛旓細杩欎竴涓樁娈甸渶瑕佸涔犵殑鍐呭涔熸槸姣旇緝澶氱殑锛屼緥濡傦細鐖櫕涓庢暟鎹佸绾跨▼鐖櫕銆乬o璇█銆丯oSQL鏁版嵁搴撱Scrapy-Redis妗嗘灦銆傞渶瑕佹帉鎻$埇铏殑宸ヤ綔鍘熺悊鍜岃璁℃濇兂锛屾帉鎻″弽鐖櫕鏈哄埗锛屽苟涓旈氳繃瀛︿範NoSQL鏁版嵁搴撳拰Scrapy-Redis妗嗘灦锛屽苟涓斿彲浠ヤ娇鐢鍒嗗竷寮鐖櫕妗嗘灦瀹炵幇澶ч噺鏁版嵁鐨勮幏鍙栥傛暟鎹垎鏋愬拰浜哄伐鏅鸿兘闃舵闇瑕佸涔犵殑鏁版嵁鍒嗘瀽銆佷汉宸...
绛旓細master鐨勭埇铏繍琛屾椂浼氭妸鎻愬彇鍒扮殑url灏佽鎴恟equest鏀惧埌redis涓殑鏁版嵁搴擄細鈥渄moz:requests鈥濓紝骞朵笖浠庤鏁版嵁搴撲腑鎻愬彇request鍚庝笅杞界綉椤碉紝鍐嶆妸缃戦〉鐨勫唴瀹瑰瓨鏀惧埌redis鐨鍙︿竴涓暟鎹簱涓渄moz:items鈥漵lave浠巑aster鐨剅edis涓彇鍑哄緟鎶撳彇鐨剅equest锛屼笅杞藉畬
绛旓細4.Python鐖櫕妗嗘灦Scrapy鐨鐔熺粌浣跨敤 5.Python鐖櫕浼涓唬鐞咺P銆乁serAgent鐨勭啛缁冧娇鐢 6.Python涓scrapyt-redis鍒嗗竷寮鐖櫕鐨勫熀鏈娇鐢 7.Python鎿嶄綔Mysql鏁版嵁搴撳鍒犳敼鏌 8.Python鎿嶄綔MongoDB鏁版嵁搴撳鍒犳敼鏌 9.Python寤虹珛鏁版嵁搴撹繛鎺ユ睜鎻愰珮鏁堢巼 10.鍥㈤槦鍗忎綔寮鍙戝伐鍏穏it鐨勭啛缁冧娇鐢 11.鐔熸倝Linux鏃ュ父宸ヤ綔鐜锛岀啛缁...
绛旓細python鍩硅闇瑕4涓湀鍒6涓湀宸﹀彸銆傚闇瀛︿範python鎺ㄨ崘閫夋嫨銆愯揪鍐呮暀鑲层戯紝璇ユ満鏋勫埗瀹氳涓氬煿璁爣鍑嗭紝涓鸿揪鍐呭鍛樻彁渚涢珮绔妧鏈佹墍瀛﹁绋嬪彈鍥介檯鍘傚晢璁ゅ彲锛岃杈惧唴瀛﹀憳鏇村叿鍥介檯鍖栧氨涓氱珵浜夊姏銆傘怭ython瀛︿範銆戝唴瀹瑰叿浣撳涓嬶細1銆丳ython寮鍙戝熀纭锛歅ython鍩虹璇硶銆佹暟鎹被鍨嬨佸瓧绗︾紪鐮佺瓑銆2銆丳ython楂樼骇缂栫▼鍜屾暟鎹簱寮鍙戯細...