Redis:實現簡單的分散式爬蟲
阿新 • • 發佈:2019-01-10
假期在攻克爬蟲期間,調轉工作方式時有幸接觸了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的官方教程~