irpas技术客

爬虫学习笔记(十三)—— scrapy-redis(二):存储到MySQL、Scrapy项目部署_别呀

大大的周 5404

文章目录 一、小案例:爬取纵横小说(RedisCrawlSpider)1.1、spider文件1.2、settings文件 二、redis数据存储到MySQL三、Scrapy 项目部署3.1、安装 scrapyd3.2、scrapy.cfg设置3.3、执行打包命令3.4、启动爬虫3.5、关闭爬虫


一、小案例:爬取纵横小说(RedisCrawlSpider)

这里修改我们 Scrapy框架(三):CrawSpider模板的案例实现伪分布式(下面我仅写有修改部分的代码)

1.1、spider文件 import json import datetime import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from ..items import BookItem,ChapterItem,CatalogItem from scrapy_redis.spiders import RedisCrawlSpider #1.导入RedisCrawlSpider class ZhSpider(RedisCrawlSpider): #2.原来是继承CrawlSpider 现在改为RedisCrawlSpider name = 'zh' # allowed_domains = ['book.zongheng.com'] # start_urls = ['http://book.zongheng.com/store/c0/c0/b0/u0/p1/v9/s1/t1/u0/i1/ALL.html'] #一定要注释掉start_urls redis_key = "zh:start_urls" #3.设置 redis_key rules = ( Rule(LinkExtractor(allow=r'http://book.zongheng.com/book/\d+.html',restrict_xpaths='//div[@class="bookname"]'), callback='parse_book', follow=True,process_links='get_booklink'), Rule(LinkExtractor(allow=r'http://book.zongheng.com/showchapter/\d+.html'), callback='parse_catalog', follow=True), Rule(LinkExtractor(allow=r'http://book.zongheng.com/chapter/\d+/\d+.html',restrict_xpaths='//ul[@class="chapter-list clearfix"]'), callback='parse_chapter',follow=False,process_links='get_chapterlink'), ) def get_booklink(self,links): for index,link in enumerate(links): print(index,link.url) if index<=30: yield link else: return def get_chapterlink(self,links): for index,link in enumerate(links): if index<=1: yield link else: return ············· 1.2、settings文件 # 启用调度将请求存储进redis SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 确保所有spider通过redis共享相同的重复过滤。 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" #公共管道 与 本地管道 ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline':300, 'zhnovel.pipelines.ZhnovelPipeline': 200, } # 指定连接到Redis时要使用的主机和端口。 REDIS_HOST = 'localhost' REDIS_PORT = 6379 # 不清理redis队列,允许暂停/恢复抓取。 # 可选 允许暂定,redis数据不丢失 SCHEDULER_PERSIST = True #日志时间输出格式 LOG_DATEFORMAT='%Y'

结果执行步骤: 1、准备(除了写入的表名,这两文件代码完全一模一样):

数据库的novel(存储书名及相关信息)和chapter(存储各个章节)表都复制一份

2、在终端分布运行这两个文件(由于还没在redis设置钥匙,所以这两文件都处于等待状态)

3、再开启一个终端(redis写入钥匙)

最后让我们来看看结果是什么样的(这里我爬取了31本书): ① 首先我们先看下redis数据库里面的数据:

可以看到总共有31本书

② 然后我们先打开MySQL数据库:

两个张表里的数据加起来刚好31条,说明我们的伪分布式是成功的(这里章节结果爬取不演示了)。


二、redis数据存储到MySQL

因为开启了公共管道,所以两个项目的公共区域 redis 里会有两个项目的数据,是完整的数据,可以持久化到MySQL里进行持久化的存储

原因:redis存储是基于内存的,数据多可能会影响运行速度,所以要对redis中的数据进行持久化

下面的是 redis数据存储到MySQL 的一般书写形式(仅供参考):

import redis import pymysql import json # 创建redis数据库连 rediscli = redis.StrictRedis(host= '127.0.0.1', port = 6379, db = 0) # 创建mysql数据库连接 mysql_conn = pymysql.connect(host="127.0.0.1", port=3306, user="xxx", passwd="xxx", db="数据库名") while True: # 将数据从redis里取出来 source, data = rediscli.blpop("表名:items") item = json.loads(data) # 创建mysql 操作游标对象,可以执行mysql语句 cursor = mysql_conn.cursor() cursor.execute("insert into 表名 (username, age) values (%s, %s)", [item['username'], item['age']]) # 提交事务 mysql_conn.commit() # 关闭游标 cursor.close()

示例: (redis里的数据是案例存进去的)

import redis import pymysql import json # 创建redis数据库连 rediscli = redis.StrictRedis(host= '127.0.0.1', port = 6379, db = 0) # 创建mysql数据库连接 mysql_conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="123456", db="zhnovel",charset="utf8") while True: # 将数据从redis里取出来 source, data = rediscli.blpop("zh:items") item = json.loads(data) print('source = ',source) print('data = ',data) # 创建mysql 操作游标对象,可以执行mysql语句 cur = mysql_conn.cursor() # 注意!!! 要提前建表 if 'book_name' in data: sql = "select id from novel_copy where book_name=%s and author=%s" cur.execute(sql, (item['book_name'], item['author'])) if not cur.fetchone(): sql = "insert into novel_copy(category,book_name,author,status,book_nums,description,book_url,catalog_url) values(%s,%s,%s,%s,%s,%s,%s,%s)" cur.execute(sql, ( item['category'], item['book_name'], item['author'], item['status'], item['book_nums'], item['description'], item['book_url'], item['catalog_url'])) elif 'chapter_list' in data: sql = 'insert into chapter_redisTomysql(title,ord_num,chapter_url,catalog_url) values(%s,%s,%s,%s)' data_list = [] for index, chapter in enumerate(item['chapter_list']): ord_num = index + 1 title, chapter_url, catalog_url = chapter data_list.append((title, ord_num, chapter_url, catalog_url)) cur.executemany(sql, data_list) elif 'content' in data: sql = "update chapter_redisTomysql set content=%s where chapter_url=%s" cur.execute(sql, (item['content'], item['chapter_url'])) mysql_conn.commit() # 关闭游标 cur.close() mysql_conn.close()

结果:


三、Scrapy 项目部署 3.1、安装 scrapyd

命令1:

pip install scrapyd

验证:

输入 scrapyd ,可以点击页面则成功

命令2:

?pip install scrapyd-client

验证:

到 scrapy 项目下面,输入 scrapyd-deploy ,出现

Unknown target: defaultg
3.2、scrapy.cfg设置 [settings] default = zhnovel.settings [deploy:novel] ;#novel:部署名称随便取 可以无 默认为空 ;取消注释 url必须有,可以是远程服务器 url = http://localhost:6800/ ;项目名称 project = zhnovel ;访问服务器需要的用户名和密码 (可以不写) ;username=xxx ;password=xxx

终端输入命令 scrapyd-deploy -l 查看设置的部署名称 和 url


3.3、执行打包命令

位置: 在有scrapy.cfg 的目录下

输入 scrapyd-deploy spider(部署名称) -p zongheng(项目名称)

终端显示如下:

Deploying to project "zhnovel" in http://localhost:6800/addversion.json Server response (200): {"node_name": "DESKTOP-ISNG60N", "status": "ok", "project": "zhnovel", "version": "1626959536", "spiders": 1}

输入 http://127.0.0.1:6800 网页端显示如下:


3.4、启动爬虫

命令: curl http://localhost:6800/schedule.json -d project=项目名称 -d spider=爬虫文件名

显示如下:

建议使用cmd,打开命令行执行该语句,不然可能会出现报错


3.5、关闭爬虫

命令:curl http://localhost:6800/cancel.json -d project=项目名 -d job=填jobid值


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #爬虫学习笔记十三 #redis #里会有两个项目的数据 #redis数据存储到MySQL