1、python操作redis
①导入redis库pip install redis -i https://pypi.douban.com/simple
②python连接redis直接操作数据库(别忘了书写pyton代码要符合pep8规则哦)
import redis
# 连接的redis的两方式
# redis.Redis()
# redis.StrictRedis()观察源码可知两种方式相等
class RedisTest():
def __init__(self):
self.r = redis.StrictRedis(host='127.0.0.1', port=6379, decode_responses=True)
def set_user(self, k, v):
res = self.r.set(k, v)
print(res)
def get_user(self, k):
res = self.r.get(k)
return res
if __name__ == '__main__':
t = RedisTest()
# t.set_user('name', 'heiei')
print(t.get_user('name'))
print(type(t.get_user('name')))
# b'heihei'
# <class 'bite'>
# 如果默认以decode_responses=False连接数据库操作的数据格式是字节bite,所以要改为True才可以变为str
# heihei
# <class 'str'>
2、scrapy_redis的学习
2.1scrapy和scrapy_redis有什么区别
接下来的是通过案例讲解,案例需要留言,或者直接看理论也ok
scrapy是一个爬虫框架,爬取效率很高,但是不支分布式
scrapy_redis有一套基于redis的数据库,运行在scrapy框架之上的组件,可以让scrapy支持分布式策略
2.2scrapy_redis有哪些优点
①它支持主从同步读写分离,数据是缓存在内存中,对于高频请求非常友好
②它会自动将请求过的request请求保存在数据库中,做去重请求
再命令行中scrapy crawl dmoz之后会再redis中的第一个数据库中发现如下三个字段
2.3scrapy_redis的工作流程
2.4scrapy_redis结构
要在后面加上REDIS_URL='redis://127.0.0.1:6379'才算正真连接数据库,配置信息才会在数据库中起作用
2.5验证队列中的数据是否可以持久化存储
待续。。。
3、普通scrapy爬取当当网
创建一个普通scrapy爬虫框架爬取内容
spider逻辑
import scrapy
from copy import deepcopy
class DandanSpider(scrapy.Spider):
name = 'dandan'
allowed_domains = ['dangdang.com']
start_urls = ['http://book.dangdang.com/']
def parse(self, response):
div_list = response.xpath("//div[@class='con flq_body']/div")
for div in div_list:
item = {}
# extract() 返回列表
# extract.first() 列表中第一个数据
# 获取大分类
item['b_cate'] = div.xpath("./dl/dt//text()").extract()
# 处理格式
item['b_cate'] = [i.strip() for i in item['b_cate'] if len(i.strip()) > 0]
dl_list = div.xpath(".//dl[@class='inner_dl']")
for dl in dl_list:
# 获取中分类
item['m_cate'] = dl.xpath('./dt//text()').extract()
# 处理格式
item['m_cate'] = [i.strip() for i in item['m_cate'] if len(i.strip()) > 0]
a_list = dl.xpath('./dd/a')
for a in a_list:
# 获取小分类
item['s_cate'] = a.xpath('./text()').extract_first()
# 获取列表页面的url
item['s_href'] = a.xpath('./@href').extract_first()
# print(item)
if item['s_href'] is not None:
yield scrapy.Request(
url=item['s_href'],
callback=self.parse_book_list,
meta={'item': deepcopy(item)}
)
def parse_book_list(self, response):
# item = response.meta['item']
item = response.meta.get('item')
li_list = response.xpath("//ul[@class='list_aa ']/li")
for li in li_list:
# 获取图片的url
item['book_img'] = li.xpath('./a[@class="img"]/img/@data-original').extract_first()
# 获取图片的名字
item['book_name'] = li.xpath('./p[@class="name"]/a/@title').extract_first()
print(item)
# yield item
如果运行不成功去setting中将ua以及不遵守robots协议就可以了最好加上下载延迟
4、将普通scrapy爬虫变成scrapy_redis爬虫将数据保存再数据库中
改写成分布式scrapy_redis爬虫
1. 改写爬虫文件
1.1 导入模块
1.2 继承类
1.3 把start_urls ---> redis_key
2. 改写配置文件
直接在创建的普通爬虫框架直接修改
第一步导入模块继承类
第二步把start_urls —> redis_key,将初始url加到爬虫名中的列表中去
第三步改写配置文件
开启队列以及存储方式,开启redis管道保存到redis数据库
完整代码
import scrapy
from copy import deepcopy
from scrapy_redis.spiders import RedisSpider
class DangdangSpider(RedisSpider):
name = 'dangdang'
allowed_domains = ['dangdang.com']
# start_urls = ['http://book.dangdang.com/']
redis_key = 'dangdang'
def parse(self, response):
div_list = response.xpath("//div[@class='con flq_body']/div")
for div in div_list:
item = {}
# extract() 返回列表
# extract.first() 列表中第一个数据
# 获取大分类
item['b_cate'] = div.xpath("./dl/dt//text()").extract()
# 处理格式
item['b_cate'] = [i.strip() for i in item['b_cate'] if len(i.strip())>0]
dl_list = div.xpath(".//dl[@class='inner_dl']")
for dl in dl_list:
# 获取中分类
item['m_cate'] = dl.xpath('./dt//text()').extract()
# 处理格式
item['m_cate'] = [i.strip() for i in item['m_cate'] if len(i.strip()) > 0]
a_list = dl.xpath('./dd/a')
for a in a_list:
# 获取小分类
item['s_cate'] = a.xpath('./text()').extract_first()
# 获取列表页面的url
item['s_href'] = a.xpath('./@href').extract_first()
# print(item)
if item['s_href'] is not None:
yield scrapy.Request(
url=item['s_href'],
callback=self.parse_book_list,
meta={'item':deepcopy(item)}
)
def parse_book_list(self,response):
# item = response.meta['item']
item = response.meta.get('item')
li_list = response.xpath("//ul[@class='list_aa ']/li")
for li in li_list:
# 获取图片的url
item['book_img'] = li.xpath('./a[@class="img"]/img/@data-original').extract_first()
# 获取图片的名字
item['book_name'] = li.xpath('./p[@class="name"]/a/@title').extract_first()
# print(item)
yield item