zoukankan      html  css  js  c++  java
  • Python 用Redis简单实现分布式爬虫

    Redis通常被认为是一种持久化的存储器关键字-值型存储,可以用于几台机子之间的数据共享平台。

    连接数据库 
    注意:假设现有几台在同一局域网内的机器分别为Master和几个Slaver 
    Master连接时host为localhost即本机的ip

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

    Slaver连接时的host也为Master的ip,端口port和数据库db不写时为默认值6379、0

    _db = redis.Redis(host='192.168.235.80')

    Redis含列表、集合,字符串等几种数据结构,具体详细的几种数据结构的操作命令可查看Redis官网http://redis.io/commands,下面是对集合进行操作的一些命令

    _db.sadd(key, *values) # 插入指定values到集合中并返回新插入的的值的数量
    _db.spop(self.key) # 随机从集合中的得到一个元素将其从集合中删除并作为返回值返回
    _db.smembers(self.key) # 返回集合的所有元素
    _db.delete(key) # 删除整个集合, 成功返回1, 失败返回0
    _db.srandmember(self.key) # 从集合中随机选取一个元素作为返回
    _db.sismember(self.key, value) # 判断指定value是否在本集合中,成功返回1,失败返回0

    例如,Master可利用redis将url上传到数据库

    for i in range(20):  # 将需爬取的糗事百科前20页的url并存入urls集合
        url = 'http://www.qiushibaike.com/hot/page/%d/' % (i + 1)
        _db.sadd('urls', url) # 将url插入关键字urls集合中,若url已存在则不再插入

    进而Master和Slaver可从数据库里获取url

    url = _db.spop('urls') # 随机从urls集合中取出一个url返回并将其删去

    同理,Master可利用上面的方法将其他一些共用的资源上传到数据库,Slaver就可从数据库下载需要的东西。下面是一个完整的例子

    # 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">([wW]*?)</div>([wW]*?)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('
    ', '', x)
                        stories.append(x)
                url = job_redis.spop('urls')
                time.sleep(3)
    
            return stories
    
        def main(self):
            self.get_content()
    
    if __name__ == '__main__':
        Clawer()

    将此代码在几台机器同时运行,调节其身份为master或slaver,做到简单的分布式爬虫

  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/meng-wei-zhi/p/8259245.html
Copyright © 2011-2022 走看看