# 分散式爬蟲 & 資料監控
## Project overview
[TOC]
## 需求
1. 如何快速在同時間爬取大量網站
2. 防ban - 怎麼不被網站發現我是爬蟲
3. 隱藏身分 – 讓被抓取的網站無法追蹤IP(我是誰)
4. 爬蟲管理介面(+狀態存取)
5. 去除重複網站爬取 & 存入
## 開發概念
來自Scrapy cluster的架構,大量運用Kafka提供的broker、Producer、Consumer概念。

## 模組介紹
### Scrapy
Python的開源網絡爬蟲框架,主要使用spider作為parser,可根據需求調整抓取domain、調整header、redirection等功能。

### Scrapy-Redis
Based on Scrapy衍生的框架,其主要修改scrapy中的scheduler,透過調整scheduler,能夠使Request pool被Redis取代,將pool使用redis做分散式。

### Kafka & Zookeeper
- Zookeeper
主要用於幫助kafka做replica、負載平衡
- Kafka
Kafka是由LinkedIn開發的一個分布式的Message System,由Scala實作,它具備有水平擴充和高吞吐量的能力,而隨著新版Stream功能的加入,將自已定位為一個分散式串流平台(distributed streaming platform),來提供實時資料串接(real-time pipeline)。
### Redis
- Key-Value in-memory NoSQL
- 資料結構
- <b style="color: red">STRING</b>(string、integer、float)
ex. {key: value}
- <b style="color: red">LIST</b>(a STRING list)
ex. {key: [string, string, ...]}
- <b style="color: red">SET</b>(list with unique values)
ex. {key:{ustring1, ustring2, …}}
- <b style="color: red">HASH</b>(hash table/Dictionary)
ex.{ key: {sub_key: value}}
- <b style="color: red">ZSET</b>(Ordered Dictionary)
ex. {key: {700:value1, 900: value2, …}}
### 資料庫
- 使用MySQL關聯式資料庫

## 介紹 & 名詞定義
### 運作流程
1. 統一蒐集URL,暫存於Redis
2. UrlCollector: 取得一定量於Redis列隊的URL,同時發布到AWS Lambda進行網頁HTML下載
3. LambdaProcessor: 回傳Lambda下載的HTML,存入Redis\(另一個Queue\)等待處理
4. HtmlConsumer:
- 取得下載回存於Redis的Html\(一次只處理一個網頁\),並根據取得的資料\(Html、ParserName、該網頁的URL\),使用Parser模組丟入HTML進行解析,並回傳資訊
- 使用Generator取得Return的物件,根據物件的class,
- Scrapy.Request: 新的請求網頁,callback為Parser,加入Redis等待請求
- Scrapy.items: 解析出的資料,發布到Kafka等待Consumer處理
5. DataConsumer: crawl item的Consumer,依收到的DataType決定如何儲存\(DB\)
### UrlCollector
```
向Redis取得欲爬取的網址,並於定量後發送request
```
> 類似於原爬蟲階段的指定request
### HtmlConsumer
```
向Redis取得由AWS lambda下載回來的Html,並進行剖析
```
### StatesConsumer
```
處理Module中所記錄的state,並存入資料庫
```
### DataConsumer
```
用於蒐集HtmlConsumer解析後的資料,處理後存入資料庫
```
### ModuleLauncher
初始時須更新最新parser程式碼,且定期更新
## ModuleLauncher
Flask框架的WEB API
- 根據settings的launch_IP,紀錄此Server的服務IP,用於UI介面控制
- 運行另一個thread,負責定時向UI介面服務告知此服務仍在運行
### API
- /output: Dump此服務上各模組運行狀況
- /start_module: 運行一個新的thread,運行模組
- /stop_module: 呼叫模組的stop()方法,模組收到stop指令後跳出無限迴圈,結束此thread
- /reset: 記錄正在運行的模組,停止此服務上所有正在運行的模組,並根據先前紀錄有在運行的模組,重新分配thread給模組並開始重新運行
## UI介面
- /index
- /crawl_states
- /run_routine
- /job_list
- /get_states_list
#### index
- 觀看各模組狀況: 5秒ajax更新資料
#### crawl_states
- 觀看各模組狀況: 5秒ajax更新資料
- 錯誤排名列表\(網站\): 5秒ajax更新資料
#### run_routine
- 控制是否啟動固定時間發布任務功能
- 觀看目前有哪些爬蟲服務啟動
- 控制爬蟲服務的模組啟動或停止
#### job_list
- 觀看目前有抓哪些網站
- 控制下一次網站是否要加入任務列表
- 點選parser可進入爬蟲過程紀錄
#### get_states_list
- 給parser: 列出此parser的crawlid\(曾經發布過的任務\)
- 給crawlid: 列出此crawlid下的任務爬蟲過程
## 資料監控呈現
### 即時抓取況狀\(爬蟲\)

### 抓取網頁部屬\(控制是否抓取\)

### 近期抓取數量狀況

### 即時發布文章

### 各版\[近24HR、近7日\]數量
