1. 程式人生 > 實用技巧 >python爬蟲學習筆記(二十九)-Scrapy 框架-分散式

python爬蟲學習筆記(二十九)-Scrapy 框架-分散式

1. 介紹scrapy-redis框架

scrapy-redis

一個三方的基於redis的分散式爬蟲框架,配合scrapy使用,讓爬蟲具有了分散式爬取的功能。

github地址:
https://github.com/darkrho/scrapy-redis

2. 分散式原理

 scrapy-redis實現分散式,其實從原理上來說很簡單,這裡為描述方便,我們把自己的核心伺服器稱為master,而把用於跑爬蟲程式的機器稱為slave

我們知道,採用scrapy框架抓取網頁,我們需要首先給定它一些start_urls,爬蟲首先訪問start_urls裡面的url,再根據我們的具體邏輯,對裡面的元素、或者是其他的二級、三級頁面進行抓取。而要實現分散式,我們只需要在這個starts_urls裡面做文章就行了

我們在master上搭建一個redis資料庫`(注意這個資料庫只用作url的儲存),並對每一個需要爬取的網站型別,都開闢一個單獨的列表欄位。通過設定slave上scrapy-redis獲取url的地址為master地址。這樣的結果就是,儘管有多個slave,然而大家獲取url的地方只有一個,那就是伺服器master上的redis資料庫

並且,由於scrapy-redis自身的佇列機制,slave獲取的連結不會相互衝突。這樣各個slave在完成抓取任務之後,再把獲取的結果彙總到伺服器上

好處

程式移植性強,只要處理好路徑問題,把slave上的程式移植到另一臺機器上執行,基本上就是複製貼上的事情

3.分散式爬蟲的實現

  1. 使用三臺機器,一臺是win10,兩臺是centos6,分別在兩臺機器上部署scrapy來進行分散式抓取一個網站

  2. win10的ip地址為192.168.31.245,用來作為redis的master端,centos的機器作為slave

  3. master的爬蟲執行時會把提取到的url封裝成request放到redis中的資料庫:“dmoz:requests”,並且從該資料庫中提取request後下載網頁,再把網頁的內容存放到redis的另一個數據庫中“dmoz:items”

  4. slave從master的redis中取出待抓取的request,下載完網頁之後就把網頁的內容傳送回master的redis

  5. 重複上面的3和4,直到master的redis中的“dmoz:requests”資料庫為空,再把master的redis中的“dmoz:items”資料庫寫入到mongodb中

  6. master裡的reids還有一個數據“dmoz:dupefilter”是用來儲存抓取過的url的指紋(使用雜湊函式將url運算後的結果),是防止重複抓取的

4. scrapy-redis框架的安裝

pip install scrapy-redis

5. 部署scrapy-redis

5.1 slave端

在windows上的settings.py檔案的最後增加如下一行

REDIS_HOST = 'localhost' #master IP

REDIS_PORT = 6379

配置好了遠端的redis地址後啟動兩個爬蟲(啟動爬蟲沒有順序限制)

6 給爬蟲增加配置資訊

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}


7 執行程式

7.1 執行slave
scrapy runspider 檔名.py

開起沒有先後順序

7.2 執行master
lpush (redis_key)  url #括號不用寫

說明

  • 這個命令是在redis-cli中執行
  • redis_key 是 spider.py檔案中的redis_key的值
  • url 開始爬取地址,不加雙引號

8 資料匯入到mongodb中

等到爬蟲結束後,如果要把資料儲存到mongodb中,就應該修改master端process_items.py檔案,如下

import redis

import pymongo

def main():

    r = redis.Redis(host='192.168.31.245',port=6379,db=0)

    client = pymongo.MongoClient(host='localhost', port=27017)

    db = client.dmoz

    sheet = db.sheet

    while True:


        source, data = r.blpop(["dmoz:items"])

        item = json.loads(data)

        sheet.insert(item)

if __name__ == '__main__':

    main()

9 資料匯入到MySQL中

等到爬蟲結束後,如果要把資料儲存到mongodb中,就應該修改master端process_items.py檔案,如下

import redis
import pymysql
import json
def process_item():
    r_client = redis.Redis(host="127.0.0.1",port=6379,db =0)
    m_client = pymysql.connect(host="127.0.0.1",port=3306,user="root",passowrd="123456",db="lianjia")
    source,data =r_client.blpop("lianjia:item")
    item = json.loads(data)

    cursor = m_client.cursor()
    values = []
    cursor.execute(sql,values)