[Python]200个激活码保存到Redis非关系型数据库中

本文介绍了Redis的安装过程及常见问题解决方法,并提供了一段Python代码示例,用于生成200个16位随机激活码并将其保存至Redis数据库。

第 0003 题:将 0001 题生成的 200 个激活码(或者优惠券)保存到 Redis 非关系型数据库中。

 这个主要涉及到redis安装,我之前直接执行语句,pip install redis,显示安装成功,但运行一直报错,后来了解到要运行redis,网上有很多教程给的一个GitHub的地址,找到bin文件进行安装,但那个文件已经更新了版本,没有bin文件了,所以很多教程都失效了,我也不会配置,后来找到一个新的安装教程,[链接](http://blog.youkuaiyun.com/erlian1992/article/details/54382443)按照他前面的步骤可以完成redis安装,在运行程序之前启动redis服务,运行过程中不关闭窗口就可以了。保存到数据库中的操作比较简单。

代码如下:

#coding=utf-8
import redis
import random

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

list=[]
#生成26个大写的字母
for x in range(65,91):
    a=str(chr(x))  #生成对应的ASCII码对应的字符串
    list.append(a)
#生成26个小写字母
for x in range(97,123):
    a=str(chr(x))  #生成对应的ASCII码
    list.append(a)     
#生成10个数字
for x in range(10):
    list.append(str(x))
'''
def gen_code():
    a=random.sample(list,16)
    print a
'''
#生成16位激活码
def gen_code():
    s=''
    for x in range(16):
        a=random.choice(list)
        s=s+a
    return s

#生成200个激活码
for x in range(200):
    code=gen_code()
    r.set(x,code)

print 'END'
<think>我们正在构建一个分布式爬虫,并将数据保存到远程MySQL服务器。同时,我们也希望支持MongoDB、Redis和Elasticsearch作为存储选项。考虑到分布式爬虫的特点,我们需要设计一个灵活的存储后端,可以配置不同的存储方式。步骤:1.分布式爬虫框架选择:Scrapy-Redis是一个常用的分布式爬虫框架,它基于Redis实现分布式调度。2.数据存储设计:我们需要编写一个可扩展的数据存储管道(pipeline),以便支持多种存储引擎。我们将按照以下步骤进行:一、搭建分布式爬虫环境(使用Scrapy-Redis)二、配置远程MySQL、MongoDB、Redis、Elasticsearch的连接信息三、编写存储管道(pipeline)以支持多种存储方式详细步骤:一、搭建分布式爬虫环境1.安装必要的库:scrapy,scrapy-redis,redis2.创建Scrapy项目,配置使用Scrapy-Redis调度器。二、配置存储服务的连接信息我们可以在Scrapy项目的settings.py中配置不同存储的连接字符串,例如:MYSQL_HOST='remote_host'MYSQL_PORT=3306MYSQL_USER='user'MYSQL_PASSWORD='password'MYSQL_DB='database_name'同样,配置MongoDB、Redis、Elasticsearch的连接信息。三、编写存储管道我们将为每种存储方式编写一个管道类,然后在settings.py中激活需要使用的管道。示例管道:1.MySQL管道:将数据存储到MySQL2.MongoDB管道:将数据存储到MongoDB3.Redis管道:将数据存储到Redis(例如作为缓存或消息队列)4.Elasticsearch管道:将数据存储到Elasticsearch(用于搜索)我们可以同时使用多个管道,这样爬取的数据可以同时存入多个存储系统。代码示例:1.MySQL管道(pipelines.py):需要安装pymysql或mysql-connector-python2.MongoDB管道(pipelines.py):需要安装pymongo3.Elasticsearch管道(pipelines.py):需要安装elasticsearch4.Redis管道(pipelines.py):注意:Redis通常用作缓存或消息队列,因此存储方式可能是以键值对的形式存储数据,或者作为其他用途。这里可以根据需求设计。下面分别给出这些管道的示例代码:注意:在settings.py中配置管道优先级,例如:ITEM_PIPELINES={'myproject.pipelines.MySQLPipeline':300,'myproject.pipelines.MongoDBPipeline':400,'myproject.pipelines.ElasticsearchPipeline':500,'myproject.pipelines.RedisPipeline':600,}每个管道类中,我们都需要在open_spider方法中建立连接,在close_spider方法中关闭连接,在process_item方法中处理数据。考虑到分布式爬虫可能同时运行多个爬虫节点,存储系统应该能够处理并发写入。具体代码实现:1.MySQL管道示例:在settings.py中配置MySQL连接信息:MYSQL_HOST='your_remote_mysql_host'MYSQL_PORT=3306#默认端口MYSQL_USER='username'MYSQL_PASSWORD='password'MYSQL_DB='database_name'MYSQL_TABLE='table_name'在pipelines.py中:importpymysqlfrom.settingsimportMYSQL_HOST,MYSQL_PORT,MYSQL_USER,MYSQL_PASSWORD,MYSQL_DB,MYSQL_TABLEclassMySQLPipeline:defopen_spider(self,spider):self.connection=pymysql.connect(host=MYSQL_HOST,port=MYSQL_PORT,user=MYSQL_USER,password=MYSQL_PASSWORD,db=MYSQL_DB,charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)self.cursor=self.connection.cursor()defclose_spider(self,spider):self.connection.close()defprocess_item(self,item,spider):#根据item构建SQL语句keys=','.join(item.keys())values=','.join(['%s']*len(item))sql=f'INSERTINTO{MYSQL_TABLE}({keys})VALUES({values})'self.cursor.execute(sql,tuple(item.values()))self.connection.commit()returnitem2.MongoDB管道示例:在settings.py中配置MongoDB连接信息:MONGODB_URI='mongodb://user:password@remote_host:27017/'MONGODB_DB='database_name'MONGODB_COLLECTION='collection_name'在pipelines.py中:importpymongofrom.settingsimportMONGODB_URI,MONGODB_DB,MONGODB_COLLECTIONclassMongoDBPipeline:defopen_spider(self,spider):self.client=pymongo.MongoClient(MONGODB_URI)self.db=self.client[MONGODB_DB]self.collection=self.db[MONGODB_COLLECTION]defclose_spider(self,spider):self.client.close()defprocess_item(self,item,spider):self.collection.insert_one(dict(item))returnitem3.Elasticsearch管道示例:在settings.py中配置Elasticsearch连接信息:ES_HOSTS=['http://remote_host:9200']#可以是多个节点ES_INDEX='index_name'ES_USER='username'#如果需要认证ES_PASSWORD='password'在pipelines.py中:fromelasticsearchimportElasticsearchfrom.settingsimportES_HOSTS,ES_USER,ES_PASSWORD,ES_INDEXclassElasticsearchPipeline:defopen_spider(self,spider):self.es=Elasticsearch(ES_HOSTS,http_auth=(ES_USER,ES_PASSWORD)ifES_USERandES_PASSWORDelseNone)defprocess_item(self,item,spider):#将item转换为文档doc=dict(item)#使用id或者由Elasticsearch自动生成_idself.es.index(index=ES_INDEX,document=doc)returnitem#注意:由于Elasticsearch客户端是长连接,可以不需要在close_spider中做特别处理,但为了规范我们可以关闭连接?#实际上,Elasticsearch客户端不需要显式关闭,但我们可以关闭来释放资源。defclose_spider(self,spider):self.es.close()4.Redis管道示例:在settings.py中配置Redis连接信息:REDIS_HOST='remote_host'REDIS_PORT=6379REDIS_PASSWORD=None#如果有密码则配置REDIS_DB=0#选择数据库在pipelines.py中:importredisimportjsonfrom.settingsimportREDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_DBclassRedisPipeline:defopen_spider(self,spider):self.client=redis.Redis(host=REDIS_HOST,port=REDIS_PORT,password=REDIS_PASSWORD,db=REDIS_DB)defprocess_item(self,item,spider):#Redis通常以键值对存储。这里我们使用一个列表或者集合来存储item,或者使用哈希表?#具体方式取决于需求:如果作为缓存,我们可以设置一个过期时间;如果作为数据存储,我们可以考虑永久存储。#这里我们使用字符串类型存储,将item转为json字符串,然后以一个键名存储(注意键名的设计,例如使用spider.name和item的id)#假设item有一个'id'字段key=f"{spider.name}:{item['id']}"#或者如果不需要单独存储每个item,而是用列表存储,可以使用lpush#这里以字符串形式存储每个itemself.client.set(key,json.dumps(dict(item)))#或者使用哈希表:hmset(注意:hmset在redis-py中可以使用hset替代,因为hmset已被弃用)#以哈希表存储的例子(如果item字段较多,且需要单独访问某些字段,可以用哈希):#self.client.hset(key,mapping=dict(item))#我们这里简单用字符串存储returnitemdefclose_spider(self,spider):self.client.close()#redis连接不需要显式关闭?redis-py的连接是使用连接池的,但显式关闭连接是好的做法注意:以上代码示例均为基本实现,实际使用中需要根据数据结构和需求调整。同时,为了提高性能,可以考虑批量写入(如MySQL的批量插入、MongoDB的批量插入、Elasticsearch的批量API)。四、分布式爬虫节点配置使用Scrapy-Redis时,配置settings.py:#使用scrapy_redis的调度器SCHEDULER="scrapy_redis.scheduler.Scheduler"#使用scrapy_redis的去重组件DUPEFILTER_CLASS="scrapy_redis.dupefilter.RFPDupeFilter"#允许爬取后暂停,然后继续(不清空队列)SCHEDULER_PERSIST=True#指定连接Redis的信息REDIS_HOST='remote_redis_host'REDIS_PORT=6379#如果Redis有密码#REDIS_PASSWORD='password'在爬虫中,从Redis队列获取起始URL,例如:fromscrapy_redis.spidersimportRedisSpiderclassMyDistributedSpider(RedisSpider):name='distributed_spider'redis_key='my_spider:start_urls'#Redis中的键,用于获取起始URL这样,多个爬虫节点会从同一个Redis队列中获取任务。五、部署到多个节点将爬虫代码部署到多台服务器上,并启动爬虫。确保所有爬虫节点可以访问Redis服务(用于任务调度)以及各个存储服务(MySQL,MongoDB,etc.)。六、启动爬虫在Redis中推送起始URL(lpush):lpushmy_spider:start_urlshttp://example.com/page1然后在各个节点运行爬虫:scrapyrunspidermyspider.py这样,我们就搭建了一个分布式爬虫,并将数据存储到多种存储系统中。额外加分:支持MongoDB、Redis或Elasticsearch存储,我们已经在管道中实现了。注意:以上代码仅为示例,实际应用中需要考虑错误处理、数据去重、增量爬取等问题。参考文献:[1]Scrapy-Redis文档:https://github.com/rmax/scrapy-redis[2]PyMySQL文档:https://pypi.org/project/PyMySQL/[3]PyMongo文档:https://pymongo.readthedocs.io/en/stable/[4]ElasticsearchPython客户端文档:https://elasticsearch-py.readthedocs.io/[5]Redis-py文档:https://redis-py.readthedocs.io/</think> ### 分布式爬虫数据存储方案(支持 MySQL/MongoDB/Redis/Elasticsearch) 以下是一个完整的分布式爬虫架构实现方案,重点解决数据存储到远程 MySQL 节点,并支持 MongoDB、Redis 和 Elasticsearch 多存储方案: #### 一、系统架构设计 ``` ┌─────────────────┐ ┌──────────────────┐ ┌──────────────┐ │ 分布式爬虫节点 │───▶ │ 消息队列 │───▶ │ 数据存储层 │ │ (Scrapy-Redis) │ │ (Redis/RabbitMQ) │ │ (多存储支持) │ └─────────────────┘ └──────────────────┘ └──────────────┘ ▲ │ │ ▼ └───────────────┐ ┌───────────────┐ │ │ 数据消费服务 │ └──────┤ (Python Worker)│ └───────────────┘ ``` #### 二、核心实现步骤 **1. 分布式爬虫框架搭建 (使用 Scrapy-Redis)** ```python # settings.py SCHEDULER = "scrapy_redis.scheduler.Scheduler" DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" REDIS_URL = 'redis://:<password>@<redis-host>:6379/0' # Redis连接地址 # pipelines.py (数据推送到消息队列) class RedisPipeline: def process_item(self, item, spider): redis_conn.lpush('crawler:items', json.dumps(dict(item))) return item ``` **2. 数据存储服务实现 (核心存储逻辑)** ```python class StorageService: def __init__(self): # 初始化所有数据库连接 self.mysql_conn = pymysql.connect( host='mysql-host', user='user', password='pass', database='db' ) self.mongo_client = pymongo.MongoClient( 'mongodb://user:pass@mongo-host:27017/' ) self.es = Elasticsearch(['http://es-host:9200']) self.redis = redis.Redis(host='redis-host', port=6379) def save_to_mysql(self, item): with self.mysql_conn.cursor() as cursor: sql = """INSERT INTO scraped_data (url, title, content) VALUES (%s, %s, %s)""" cursor.execute(sql, (item['url'], item['title'], item['content'])) self.mysql_conn.commit() def save_to_mongodb(self, item): self.mongo_client.crawler.data.insert_one({ 'url': item['url'], 'title': item['title'], 'timestamp': datetime.now() }) def save_to_elasticsearch(self, item): self.es.index( index='web-content', document={ 'url': item['url'], 'content': item['content'] } ) def save_to_redis(self, item): self.redis.hset(f'page:{item["id"]}', mapping=item) def process_item(self, item_data): item = json.loads(item_data) # 根据配置选择存储引擎 if STORAGE_ENGINE == 'mysql': self.save_to_mysql(item) elif STORAGE_ENGINE == 'mongodb': self.save_to_mongodb(item) ... ``` **3. 多存储引擎配置** ```python # config.py STORAGE_ENGINE = 'mysql' # 可选:mysql/mongodb/elasticsearch/redis/all # 同时支持多引擎写入 if STORAGE_ENGINE == 'all': self.save_to_mysql(item) self.save_to_mongodb(item) self.save_to_elasticsearch(item) self.save_to_redis(item) ``` **4. 部署方案** 1. **数据库准备** (所有存储引擎需要预先配置): ```bash # MySQL CREATE DATABASE crawler; CREATE TABLE scraped_data(id INT AUTO_INCREMENT PRIMARY KEY, ...); # MongoDB use crawler db.createCollection("data") # Elasticsearch PUT /web-content { "mappings": { ... } } ``` 2. **Docker 部署数据库** [^3]: ```bash # 启动MySQL容器 docker run --name mysql -e MYSQL_ROOT_PASSWORD=pass -p 3306:3306 -d mysql:8 # 启动MongoDB容器 docker run --name mongo -p 27017:27017 -d mongo # 启动Elasticsearch容器 docker run --name es -p 9200:9200 -p 9300:9300 -d docker.elastic.co/elasticsearch/elasticsearch:8.5.1 ``` 3. 分布式部署爬虫节点: ```bash # 在所有爬虫节点 scrapy runspider myspider.py ``` #### 三、性能优化建议 1. **批量写入**:MySQL/MongoDB/ES 支持批量写入 2. **连接池**:为每个存储引擎配置连接池 3. **数据分片**:对MySQL分表、MongoDB分片、ES分片[^2] 4. **Redis缓存队列**:使用LPUSH/BRPOP模式提升吞吐量 #### 四、存储引擎选择建议 | 存储引擎 | 最佳场景 | 性能基准[^1] | |--------------|-----------------------------|----------------------| | **MySQL** | 关系型数据/事务性需求 | 10k-20k TPS | | **MongoDB** | 非结构化数据/灵活schema | 30k-50k 写入/秒 | | **Elasticsearch** | 全文搜索/日志分析 | 10k-15k 文档/秒 | | **Redis** | 实时缓存/去重队列 | 100k+ 操作/秒 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值