假期在攻克爬虫期间,调转工作方式时有幸接触了redis,真心觉得它是一个好玩的东西,接下来就是我假期的一点点小收获吧~
什么是redis
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。还提供list,set,zset,hash等数据结构的存储。支持数据的备份,即master-slave模式的数据备份。
redis实现分布式爬虫
按照我个人的理解,可以看下图:
作为本地机的Master向平台投入相应的东西,由平台自动分配给其他的各个分机即slave,相互之间不会冲突,相当于一个老板丢工作给他的奴隶,不用他亲自上阵。
但是前提是需要在redis的数据平台中创建相应的队列即Queue存储Master投入的东西,给队列命名,方便后面的slave拿对东西。
redis的使用(基于Ubuntu系统)
1.下载redis
进入官网:https://redis.io/download
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的官方教程~
[1]: http://oh4g14vir.bkt.clouddn.com/redis.png