1. 程式人生 > >Redis:實現簡單的分散式爬蟲

Redis:實現簡單的分散式爬蟲

假期在攻克爬蟲期間,調轉工作方式時有幸接觸了redis,真心覺得它是一個好玩的東西,接下來就是我假期的一點點小收穫吧~

什麼是redis

Redis 是完全開源免費的,遵守BSD協議,是一個高效能的key-value資料庫。支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。還提供list,set,zset,hash等資料結構的儲存。支援資料的備份,即master-slave模式的資料備份。

redis實現分散式爬蟲

按照我個人的理解,可以看下圖:
此處輸入圖片的描述
作為本地機的Master向平臺投入相應的東西,由平臺自動分配給其他的各個分機即slave,相互之間不會衝突,相當於一個老闆丟工作給他的奴隸,不用他親自上陣。
但是前提是需要在redis的資料平臺中建立相應的佇列即Queue儲存Master投入的東西,給佇列命名,方便後面的slave拿對東西。

redis的使用(基於Ubuntu系統)

1.下載redis

2.安裝伺服器

sudo apt-get install redis-server

3.檢查是否正常啟動

redis-cli
# 該命令會開啟如下Redis提示:
127.0.0.1:6379> 
# 輸入ping
127.0.0.1:6379> ping
PONG
# 說明成功安裝

4.如果本機作為Master,需要進行一點修改

# 安裝redis後在本機會有一個redis檔案
cd etc/redis
#  修改redis的配置(由於需要改變它的許可權還可能不能被修改,因此直接開終端的編輯器)
vi redis.conf # 將檔案中的 # bind 127.0.0.1的註釋去掉即可

5.在分機需要進行步驟1、2,本機的伺服器不能關閉

6.細化操作

(1)本機

host = '127.0.0.1'
_db = redis.Reds(host='localhost', port=6379, db=0)

(2)分機

host = '本機的IP'
_db = redis.Redis(host='192.168.235.80')

(3)檢視本機的IP

ifconfig

(4)出錯了則殺死程序重新開啟redis

# 檢視程序
ps
# 殺死進行
kill 程序號

7.具體程式碼實現

# coding=utf-8
import urllib2
import re
import time
import redis

headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/49.0.2623.108 Chrome/49.0.2623.108 Safari/537.36'}
job_redis = redis.Redis(host='192.168.235.80') # host為主機的IP,port和db為預設值


class Clawer(object):

    identity = 'master'  # 或slaver

    def __init__(self):
        if self.identity == 'master':
            for i in range(20):  # 將需爬取的糗事百科前20頁的url並存入urls集合
                url = 'http://www.qiushibaike.com/hot/page/%d/' % (i + 1)
                job_redis.sadd('urls', url)
        self.main()

    def get_content(self):
        """
        從糗事百科中獲取故事
        :return: 故事列表
        """
        stories = []
        content_pattern = re.compile('<div class="content">([\w\W]*?)</div>([\w\W]*?)class="stats"') # 匹配故事內容(第一空)和是否含有圖片(第二空)的模板
        pattern = re.compile('<.*?>') # 匹配包括括號及括號內無關內容的模板
        url = job_redis.spop('urls')
        while url: # 當資料庫還存在網頁url,取出一個並爬取
            try:
                request = urllib2.Request(url, headers=headers)
                response = urllib2.urlopen(request)
                text = response.read()
            except urllib2.URLError, e: # 若出現網頁讀取錯誤捕獲並輸出
                if hasattr(e, "reason"):
                    print e.reason
            content = re.findall(content_pattern, text) # 獲取含模板內容的列表
            for x in content:
                if "img" not in x[1]: # 過濾含圖片的故事
                    x = re.sub(pattern, '', x[0])
                    x = re.sub('\n', '', x)
                    stories.append(x)
            url = job_redis.spop('urls')
            time.sleep(3)

        return stories

    def main(self):
        self.get_content()

if __name__ == '__main__':
    Clawer()

參考資料:
1.Python 用Redis簡單實現分散式爬蟲

對於redis的更深一步瞭解可以檢視redis的官方教程~