簡介:本篇文章主要針對一些對網(wǎng)絡(luò)爬蟲感興趣的初學者,快速讓你們?nèi)腴T分布式網(wǎng)絡(luò)爬蟲架構(gòu),這篇文章以草根網(wǎng)為例,大家準備好電腦跟著我一步一步走,相信花個一天的時間能對分布式與爬蟲有個很好的認識,下面我們就開始了!
安裝
1 scrapy
$ sudo pip install scrapy
ps.scrapy 安裝對于不同的環(huán)境配置都會有不同,這里我很難給出一個詳細的教程,大家根據(jù)自己的情況Google一下或者我這里推薦一些我認為不錯的
安裝好之后打開python 界面輸入
import scrapy
scrapy.__version__
,如果安裝成功應該會出現(xiàn)如下界面:

2 redis安裝:
$ sudo apt-get install redis-server
ps.redis安裝可以參考這里
3 scrapy-redis安裝:
$ sudo pip install scrapy-reids
4 mysql安裝:
請參考這里,本例中使用的是MySQL5.6.38 版本
5 sqlalchemy和PyMySQL安裝:
$ sudo pip install sqlalchemy
$ sudo pip install PyMySQL
6 git安裝:
7 其他:
實戰(zhàn)
上面安裝和配置完后,我們先把項目跑起來再說,具體的細節(jié)和流程我們后面講,下面進入正題:
1 在某個地方建立一個文件夾,放我們需要需要的項目,假設(shè)這個文件夾名稱是caogen_pjt ,后面都會用這個說。
2 打開終端,進入caogen_pjt 文件夾,我們這里需要從git上clone 兩個項目文件(master和slaver)下來:
$ git clone https://github.com/MrPaoBrother/caogen_master.git
$ git clone https://github.com/MrPaoBrother/caogen_slaver.git
成功后,如下圖:

ps. 如果有基礎(chǔ)的朋友直接按照git上的README.md 走就行,這篇文章只針對入門級別的朋友。
3 我們首先運行caogen_master 這個項目,我們進入caogen_master/run_master.py 文件,如果上面都配置好了,直接運行該文件即可:
$ python run_master.py
ps. 如果有scrapy基礎(chǔ)的朋友,直接用命令scrapy crawl caogen_master 運行也行
運行完成后,我們查看控制臺和redis數(shù)據(jù)庫,如下圖:

ps. 簡單的來說我們已經(jīng)完成了發(fā)布任務(wù)的過程,爬蟲過程中url就相當于老板發(fā)布的任務(wù),那么下面就需要員工來接收并且執(zhí)行。
4 下面我們進入caogen_slaver 項目中,同樣,我們直接進入到caogen_slaver/run_slaver.py 文件中,直接運行或者終端輸入:
$ python run_slaver.py
slaver 你可以理解為員工,員工的工作就是等待老板發(fā)布任務(wù),上面步驟3中老板已經(jīng)發(fā)布了任務(wù)了,那么運行后我們可以看到redis 數(shù)據(jù)庫中多了一些item ,如圖:

- ps. 這些
item 我們可以理解為員工做完任務(wù)后出的成果,成果當然都是老板的了,哈哈,所以把成果都放到redis 里面等待老板去取。
5 現(xiàn)在老板要做的就是回收員工的成果,所以我們回到caogen_master 文件中,找到caogen_master/process_item.py 文件,終端運行:
$ python process_items.py caogen_slaver:items -v

- ps. 很穩(wěn),老板已經(jīng)把員工的成果全部收入囊中了,那么這樣一套下來,恭喜你,你已經(jīng)入門了分布式網(wǎng)絡(luò)爬蟲,那么下面我來詳細的講解一下其中的原理和項目中的一些關(guān)鍵代碼。如果沒有跑通項目,沒關(guān)系,先看一下后面的理論部分和注意事項可能會解決你的問題。
理論部分
分布式的流程

Master->老板
url->任務(wù)
redis->存放任務(wù)和接收成果的倉庫
slaver->員工
item->員工執(zhí)行任務(wù)后的成果
MySQL->老板的小金庫
1. 老板master 先發(fā)放任務(wù)給倉庫redis 。
2. 員工slaver 從倉庫redis 中取出任務(wù)去執(zhí)行。
3. 員工slaver 做完了事后把成果放回倉庫redis 。
4. 老板master 只需要一直等待收獲成果item 就行,然后把成果item 存入自己的小金庫MySQL 。
- 項目中就這四個步驟依次循環(huán),這就是一個簡單的分布式爬蟲的基本流程,那么下面我來簡單的介紹下項目中的關(guān)鍵文件和核心代碼
項目文件簡介
- 我們先看
caogen_master 中的文件結(jié)構(gòu),如圖:

> model/caogen_scrapy.ini : 配置mysql和redis的連接信息
config.py: 根據(jù)上面的配置信息,提供實例接口
models.py: 存放一些模型對象,例中存放的是文章詳情ArticleDetail
table.txt: 存放一些建表語句,使用mysql的朋友直接運行語句就能建表。
> spiders/__init__.py : 這個不用管,你只要知道作者是power就行了,哈哈。
caogen_master.py : 這是項目的核心文件,也就是master爬蟲文件,后面會細說。
> caogen/items.py: 相當于把信息封裝成一個實體傳輸,項目中對應的就是ArticleDetailItem。
middlewares.py : 中間件文件,這個了解一下就行。
pipelines.py : 管道文件,主要就是處理傳來的item,這里用到的是scrapy-redis框架中自帶的pipeline。
settings.py : 設(shè)置文件,具體的查看后面的相關(guān)資料。
> caogen_master/process_items.py : 這就是老板把成果放入小金庫的文件,后面會有代碼詳解。
run_master.py : 啟動項目的入口文件,方便運行。
- 同理,
caogen_slaver 的文件結(jié)構(gòu)也和master 差不多,讀者自行分析。
核心代碼
# caogen_master/caogen/spiders/caogen_master.py
def send_to_redis(self, key='master:requests', value=None):
"""
將request請求放進redis
:param key:默認master服務(wù)器
:param value:url以及一些別的附帶的信息
:return:
"""
print value
print type(value)
self.redis_conn.sadd(key, value)
print "Success send to Redis!"
# caogen_master/caogen/spiders/caogen_master.py
def start_requests(self):
while True:
url = self.get_msg_from_redis()
if url:
yield scrapy.Request(url, headers=self.headers, callback=self.parse, dont_filter=True)
else:
print("Redis 數(shù)據(jù)庫為空,5秒后繼續(xù)監(jiān)測...")
time.sleep(5)
- 其中
get_msg_from_redis 函數(shù)就是從redis 中pop 一條url出來。
# caogen_slaver/caogen/settings.py
'''
啟用scrapy-redis組件
'''
# Enables scheduling storing requests queue in redis.
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# Ensure all spiders share same duplicates filter through redis.
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# Configure item pipelines
# See http://scrapy./en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
- 這里是通過配置文件
SCHEDULER= "scrapy_redis.scheduler.Scheduler"和'scrapy_redis.pipelines.RedisPipeline': 300 使用了scrapy-redis框架中的 Scheduler 和pipeline ,查看scray-redis 源碼可以發(fā)現(xiàn):
# scrapy-redis源碼中的pipelines.py
def _process_item(self, item, spider):
key = self.item_key(item, spider)
data = self.serialize(item)
self.server.rpush(key, data)
return item
# scrapy-redis源碼中的scheduler.py
def enqueue_request(self, request):
if not request.dont_filter and self.df.request_seen(request):
self.df.log(request, self.spider)
return False
if self.stats:
self.stats.inc_value('scheduler/enqueued/redis', spider=self.spider)
self.queue.push(request)
return True
這里可能有點難,沒關(guān)系,就過一下就行,整體的思路把握住了最重要。
# caogen_master/process_item.py
while processed < limit:
# Change ``blpop`` to ``brpop`` to process as LIFO.
ret = r.blpop(keys, timeout)
# If data is found before the timeout then we consider we are done.
if ret is None:
time.sleep(wait)
continue
source, data = ret
try:
item = json.loads(data)
except Exception:
logger.exception("Failed to load item:\n%r", pprint.pformat(data))
continue
try:
"""
處理item
"""
process_item(item)
# logger.debug("[%s] Processing item: %s <%s>", source, str(title), str(image_path))
logger.debug("[%s] Processing item", source)
except KeyError:
logger.exception("[%s] Failed to process item:\n%r",
source, pprint.pformat(item))
continue
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 這一段意思就是老板一直在等待倉庫中是否有成果,有的話就
process_item 這個成果,將他放入小金庫MySQL 。
ps. 里面很多函數(shù)名是重寫scrapy 框架里面的,所以函數(shù)名是固定的,這里我不講scrapy的內(nèi)部原理,詳細的可以參考后面的相關(guān)資料進行學習。
注意事項
1 這里之所以選擇草根網(wǎng)是因為針對入門級的朋友來說在網(wǎng)站的分析方面時間成本很少,且靜態(tài)網(wǎng)站不怎么更新DOM結(jié)構(gòu),對于一些剛?cè)腴T的人來說會更容易接受一些。
2 如果項目運行中缺少什么模塊,請自行根據(jù)報錯信息安裝,這里不可能給出全部的可能。
3 項目中沒有設(shè)置一些中間件,只是單純的展示一遍分布式爬蟲的基本流程,有興趣的朋友可以自己增加一些中間件比如設(shè)置代理,設(shè)置User-Agent等。
4 如果項目中在運行時有什么bug,請留言。
5 該項目要master端和slaver端一起運行才能展示效果,請注意。
6 該項目重點是了解分布式的爬蟲流程,具體的爬蟲細節(jié)以及架構(gòu)的內(nèi)部原理請參考下面給出的相關(guān)資料進行學習。
7 所有的文檔都沒有框架源碼閱讀更加詳細,有興趣的讀者可以花時間通讀一遍scrapy和scrapy-redis的源碼,會更有幫助。
總結(jié)
相信大家對分布式爬蟲有了一個新的認識,其實一點也不難,這樣做的好處就是減輕主服務(wù)器的壓力,并且增加了項目的可拓展性。
網(wǎng)絡(luò)爬蟲到后面更多的是分析網(wǎng)站,比如一些加密參數(shù)的運行分析,抓包找接口,等等,大家如果有興趣可以試著去爬淘寶,頭條,微信等一些網(wǎng)站,我前幾天也寫了一個關(guān)于網(wǎng)易云音樂評論的信息抓取,就涉及一些加密參數(shù)需要解析才能獲取真實接口。
后續(xù)應該有時間還會繼續(xù)帶來更加精彩的教程!
|