爬虫 第六讲 Scrapy框架

爬虫 第六讲 Scrapy框架

一、Scrapy框架

Scrapy简介

什么是Scrapy
scrapy是一个网页爬虫应用框架,Twisted异步网络框架(内部较复杂,大量闭包),让爬虫更快更强,可配置和可拓展性非常高,爬虫必备的技术。
模块和框架,手和身体的关系。

http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html

工作流程

1.同步和异步
在这里插入图片描述
异步:调用在发出之后,这个调用就直接返回,不管有无结果
非阻塞:关注的是程序在等待调用结果时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程

2.爬虫工作流程
在这里插入图片描述
3.队列
在这里插入图片描述

4.scrapy简单流程:
在这里插入图片描述

5.scrapy工作流程
在这里插入图片描述
(1)引擎:整个框架的核心
(2)调度:接收从引擎发过来的url,入列
(3)项目管道:数据处理(存储数据)(编写逻辑)
(4)爬虫文件:整个爬虫的解析处理(编写逻辑)
(5)下载器:发请求,获取响应
(6)下载中间件:处理引擎和下载器之间的请求与响应(用的是比较多的)(编写逻辑)
(7)爬虫中间件处理爬虫程序的响应和输出结果以及新的请求

官方工作流程图
在这里插入图片描述

Scrapy engine(引擎)总指挥:负责数据和信号的在不同模块间的传递scrapy已经实现
Scheduler(调度器)一个队列,存放引擎发过来的request请求scrapy已经实现
Downloader(下载器)下载把引擎发过来的requests请求,并返回给引擎scrapy已经实现
Spider(爬虫)处理引擎发来的response,提取数据,提取url,并交给引擎需要手写
Item Pipline(管道)处理引擎传过来的数据,比如存储需要手写
Downloader Middlewares(下载中间件)可以自定义的下载扩展,比如设置代理一般不用手写
Spider Middlewares(中间件)可以自定义requests请求和进行response过滤一般不用手写
Scrapy入门
1 创建一个scrapy项目
scrapy startproject mySpider

2 生成一个爬虫
scrapy genspider demo "demo.cn"

3 提取数据
完善spider 使用xpath等

4 保存数据
pipeline中保存数据

在命令中运行爬虫

scrapy crawl qb     # qb爬虫的名字

在pycharm中运行爬虫

from scrapy import cmdline

cmdline.execute("scrapy crawl qb".split())

pipline使用

从pipeline的字典形可以看出来,pipeline可以有多个,而且确实pipeline能够定义多个
为什么需要多个pipeline:
1 可能会有多个spider,不同的pipeline处理不同的item的内容
2 一个spider的内容可以要做不同的操作,比如存入不同的数据库中
注意:
1 pipeline的权重越小优先级越高
2 pipeline中process_item方法名不能修改为其他的名称

回顾
在这里插入图片描述
如何翻页
在这里插入图片描述

1.scrapy.Request知识点
scrapy.Request(url, callback=None, method='GET', headers=None, body=None,cookies=None, meta=None, encoding='utf-8', priority=0,
dont_filter=False, errback=None, flags=None)

常用参数为:
callback:指定传入的URL交给那个解析函数去处理
meta:实现不同的解析函数中传递数据,meta默认会携带部分信息,比如下载延迟,请求深度
dont_filter:让scrapy的去重不会过滤当前URL,scrapy默认有URL去重功能,对需要重复请求的URL有重要用途
2.item的介绍和使用
items.py

import scrapy

class TencentItem(scrapy.Item):
    # define the fields for your item here like:
    title = scrapy.Field()
    position = scrapy.Field()
    date = scrapy.Field()
3.Scrapy log信息的认知

在这里插入图片描述

2019-01-19 09:50:48 [scrapy.utils.log] INFO: Scrapy 1.5.1 started (bot: tencent)
2019-01-19 09:50:48 [scrapy.utils.log] INFO: Versions: lxml 4.2.5.0, libxml2 2.9.5, cssselect 1.0.3, parsel 1.5.0, w3lib 1.19.0, Twisted 18.9.0, Python 3.6.5 (v3
.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)], pyOpenSSL 18.0.0 (OpenSSL 1.1.0i  14 Aug 2018), cryptography 2.3.1, Platform Windows-10-10.0
.17134-SP0  ### 爬虫scrpay框架依赖的相关模块和平台的信息
2019-01-19 09:50:48 [scrapy.crawler] INFO: Overridden settings: {'BOT_NAME': 'tencent', 'NEWSPIDER_MODULE': 'tencent.spiders', 'ROBOTSTXT_OBEY': True, 'SPIDER_MO
DULES': ['tencent.spiders'], 'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/53
7.36'}  ### 自定义的配置信息哪些被应用了 
2019-01-19 09:50:48 [scrapy.middleware] INFO: Enabled extensions: ### 插件信息
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2019-01-19 09:50:48 [scrapy.middleware] INFO: Enabled downloader middlewares: ### 启动的下载器中间件
['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2019-01-19 09:50:48 [scrapy.middleware] INFO: Enabled spider middlewares: ### 启动的爬虫中间件
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2019-01-19 09:50:48 [scrapy.middleware] INFO: Enabled item pipelines: ### 启动的管道
['tencent.pipelines.TencentPipeline']
2019-01-19 09:50:48 [scrapy.core.engine] INFO: Spider opened ### 开始爬去数据
2019-01-19 09:50:48 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-01-19 09:50:48 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2019-01-19 09:50:51 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://hr.tencent.com/robots.txt> (referer: None)  ### 抓取robots协议内容
2019-01-19 09:50:51 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://hr.tencent.com/position.php?&start=#a0> (referer: None)  ### start_url发起请求
2019-01-19 09:50:51 [scrapy.spidermiddlewares.offsite] DEBUG: Filtered offsite request to 'hr.tencent.com': <GET https://hr.tencent.com/position.php?&start=>  ### 提示错误,爬虫中通过yeid交给引擎的请求会经过爬虫中间件,由于请求的url超出allowed_domain的范围,被offsitmiddleware 拦截了
2019-01-19 09:50:51 [scrapy.core.engine] INFO: Closing spider (finished) ### 爬虫关闭
2019-01-19 09:50:51 [scrapy.statscollectors] INFO: Dumping Scrapy stats: ### 本次爬虫的信息统计
{'downloader/request_bytes': 630,
 'downloader/request_count': 2,
 'downloader/request_method_count/GET': 2,
 'downloader/response_bytes': 4469,
 'downloader/response_count': 2,
 'downloader/response_status_count/200': 2,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2019, 1, 19, 1, 50, 51, 558634),
 'log_count/DEBUG': 4,
 'log_count/INFO': 7,
 'offsite/domains': 1,
 'offsite/filtered': 12,
 'request_depth_max': 1,
 'response_received_count': 2,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'start_time': datetime.datetime(2019, 1, 19, 1, 50, 48, 628465)}
2019-01-19 09:50:51 [scrapy.core.engine] INFO: Spider closed (finished)
4.Scrapy settings说明和配置

为什么需要配置文件:
配置文件存放一些公共的变量(比如数据库的地址,账号密码等)
方便自己和别人修改
一般用全大写字母命名变量名 SQL_HOST = ‘192.168.0.1’
settings文件详细信息:https://www.cnblogs.com/cnkai/p/7399573.html

Scrapy CrawlSpider说明

之前的代码中,我们有很大一部分时间在寻找下一页的URL地址或者内容的URL地址上面,这个过程能更简单一些吗?
思路:
1.从response中提取所有的标签对应的URL地址
2.自动的构造自己resquests请求,发送给引擎
目标:通过爬虫了解crawlspider的使用
生成crawlspider的命令:scrapy genspider -t crawl 爬虫名字 域名

1.LinkExtractors链接提取器

使用LinkExtractors可以不用程序员自己提取想要的url,然后发送请求。这些工作都可以交给LinkExtractors,他会在所有爬的页面中找到满足规则的url,实现自动的爬取。

class scrapy.linkextractors.LinkExtractor(
    allow = (),
    deny = (),
    allow_domains = (),
    deny_domains = (),
    deny_extensions = None,
    restrict_xpaths = (),
    tags = ('a','area'),
    attrs = ('href'),
    canonicalize = True,
    unique = True,
    process_value = None
)

主要参数讲解:
• allow:允许的url。所有满足这个正则表达式的url都会被提取。
• deny:禁止的url。所有满足这个正则表达式的url都不会被提取。
• allow_domains:允许的域名。只有在这个里面指定的域名的url才会被提取。
• deny_domains:禁止的域名。所有在这个里面指定的域名的url都不会被提取。
• restrict_xpaths:严格的xpath。和allow共同过滤链接。

2.Rule规则类

定义爬虫的规则类。

class scrapy.spiders.Rule(
    link_extractor, 
    callback = None, 
    cb_kwargs = None, 
    follow = None, 
    process_links = None, 
    process_request = None
)查看帮助命令
redis-server --help

启动服务
redis-server.exe

链接客户端
redis-cli.exe

主要参数讲解:
• link_extractor:一个LinkExtractor对象,用于定义爬取规则。
• callback:满足这个规则的url,应该要执行哪个回调函数。因为CrawlSpider使用了parse作为回调函数,因此不要覆盖parse作为回调函数自己的回调函数。
• follow:指定根据该规则从response中提取的链接是否需要跟进。
• process_links:从link_extractor中获取到链接后会传递给这个函数,用来过滤不需要爬取的链接。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class YgSpider(CrawlSpider):
    name = 'yg'
    allowed_domains = ['sun0769.com']
    start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type=4&page=0']

    rules = (
        Rule(LinkExtractor(allow=r'wz.sun0769.com/html/question/201811/\d+\.shtml'), callback='parse_item'),
        Rule(LinkExtractor(allow=r'http:\/\/wz.sun0769.com/index.php/question/questionType\?type=4&page=\d+'), follow=True),
    )

    def parse_item(self, response):
        item = {}
        item['content'] = response.xpath('//div[@class="c1 text14_2"]//text()').extract()
        print(item)
3.案例演示 爬取小程序社区

http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1

模拟登录

那么对于scrapy来说,也是有两个方法模拟登录:
• 1 直接携带cookie
• 2 找到发送post请求的URL地址,带上信息,发送请求

1.Scrapy模拟登录人人网
  • 携带cookie
2.Scrapy模拟登录github

• 发送post请求

3.Scrapy自动登录

Scrapy下载图片

1.载图片案例 爬取汽车之家图片

scrapy为下载item中包含的文件提供了一个可重用的item pipelines,这些pipeline有些共同的方法和结构,一般来说你会使用Files Pipline或者Images Pipeline
爬取汽车家
https://www.autohome.com.cn/65/#levelsource=000000000_0&pvareaid=101594

2.选择使用scrapy内置的下载文件的方法
3.选择使用scrapy内置的下载文件的方法

使用Files Pipeline下载文件,按照以下步骤完成:
• 定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files。files_urls是用来存储需要下载的文件的url链接,需要给一个列表
• 当文件下载完成后,会把文件下载的相关信息存储到item的files属性中。如下载路径、下载的url和文件校验码等
• 在配置文件settings.py中配置FILES_STORE,这个配置用来设置文件下载路径
• 启动pipeline:在ITEM_PIPELINES中设置scrapy.piplines.files.FilesPipeline:1

4.下载图片的 Images Pipeline

使用images pipeline下载文件步骤:
• 定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images。image_urls是用来存储需要下载的文件的url链接,需要给一个列表
• 当文件下载完成后,会把文件下载的相关信息存储到item的images属性中。如下载路径、下载的url和图片校验码等
• 在配置文件settings.py中配置IMAGES_STORE,这个配置用来设置文件下载路径
• 启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1

Scrapy 下载中间件

下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能
使用方法:
• 编写一个Download Middlewares和我们编写一个pipeline一样,定义一个类,然后再settings中开启
Download Middlewares默认方法:
处理请求,处理响应,对应两个方法

process_request(self,request,spider):
    当每个request通过下载中间件时,该方法被调用

process_response(self,request,response,spider):
    当下载器完成http请求,传递响应给引擎的时候调用

process_request(request,spider)

当每个Request对象经过下载中间件时会被调用,优先级越高的中间件,越先调用;该方法应该返回以下对象:None/Response对象/Request对象/抛出IgnoreRequest异常
• 返回None:scrapy会继续执行其他中间件相应的方法;
• 返回Response对象:scrapy不会再调用其他中间件的process_request方法,也不会去发起下载,而是直接返回该Response对象
• 返回Request对象:scrapy不会再调用其他中间件的process_request()方法,而是将其放置调度器待调度下载
• 如果这个方法抛出异常,则会调用process_exception方法
process_response(request,response,spider)
当每个Response经过下载中间件会被调用,优先级越高的中间件,越晚被调用,与process_request()相反;该方法返回以下对象:Response对象/Request对象/抛出IgnoreRequest异常。
• 返回Response对象:scrapy会继续调用其他中间件的process_response方法;
• 返回Request对象:停止中间器调用,将其放置到调度器待调度下载;
• 抛出IgnoreRequest异常:Request.errback会被调用来处理函数,如果没有处理,它将会被忽略且不会写进日志。

设置随机请求头

爬虫在频繁访问一个页面的时候,这个请求如果一直保持一致。那么很容易被服务器发现,从而禁止掉这个请求头的访问。因此我们要在访问这个页面之前随机的更改请求头,这样才可以避免爬虫被抓。随机更改请求头,可以在下载中间件实现。在请求发送给服务器之前,随机的选择一个请求头。这样就可以避免总使用一个请求头
测试请求头网址: http://httpbin.org/user-agent

在middlewares.py文件中

class RandomUserAgent(object):
    def process_request(self,request,spider):
        useragent = random.choice(spider.settings['USER_AGENTS'])
        request.headers['User-Agent'] = useragent

class CheckUserAgent(object):
    def process_response(self,request,response,spider):
        print(request.headers['User-Agent'])
        return response

请求头网址:http://www.useragentstring.com/pages/useragentstring.php?typ=Browser
USER_AGENTS = [ “Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)”, “Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)”, “Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)”, “Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)”, “Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6”, “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1”, “Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0”, “Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5” ]

二、Scrapy框架进阶

1.背景

随着互联网+大数据时代的来临,传统的关系型数据库已经不能满足中大型网站日益增长的访问量和数据量。这个时候就需要一种能够快速存取数据的组件来缓解数据库服务I/O的压力,来解决系统性能上的瓶颈。

2.Redis是什么?

Redis是一个高性能的,开源的,C语言开发的,键值对存储数据的nosql数据库。
NoSQL:not only sql,泛指非关系型数据库 Redis/MongoDB/Hbase Hadoop
关系型数据库:MySQL、oracle、SqlServer

3.数据库的发展历史

1.在互联网+大数据时代来临之前,企业的一些内部信息管理系统,一个单个数据库实例就能满足系统的需求
单数据库实例
2.随着系统访问用户的增多,数据量的增大,单个数据库实例已经满足不了系统的读取需求
缓存(memcache)+单数据库实例
3.缓存可以缓解系统的读取压力,但是数据量的写入压力持续增大,
缓存+主从数据库+读写分离
4.数据量再次增大,读写分离以后,主数据库的写库压力出现瓶颈、
缓存+主从数据库集群+读写分离+分库分表
5.互联网+大数据时代来临,关系型数据库不能很好的存取一些并发性高,实时性高的,并且数据格式不固定的数据。
nosql+主从数据库集群+读写分离+分库分表

4.NoSQL和SQL数据库的比较

• 适用场景不同:SQL数据库适合用于关系特别复杂的数据查询场景,nosql反之
• 事务:SQL对事务的支持非常完善,而nosql基本不支持事务
• 两者在不断的取长补短

5.Redis特性

• Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
• Redis不仅仅支持简单的key-value类型的数据,同时还提供List,set等数据类型
• Redis支持数据的备份

6.Redis有什么用?

Redis的主要作用:快速存取

7.Redis应用场景

点赞/秒杀/直播平台的在线好友列表/商品排行榜

8.Redis怎么用?

官网地址:https://redis.io/
命令地址:http://doc.redisfans.com/

Redis的五大数据类型以及应用场景

string/list/set/hash/zset

Redis的安装及启动

查看帮助命令
redis-server --help

启动服务
redis-server.exe

链接客户端
redis-cli.exe

Redis的配置文件

/etc/redis/redis.conf

当redis作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面。
daemonize no

监听端口号,默认为 6379,如果你设为 0 ,redis 将不在 socket 上监听任何客户端连接。
port 6379

设置数据库的数目。
databases 16

根据给定的时间间隔和写入次数将数据保存到磁盘
下面的例子的意思是:
900 秒内如果至少有 1 个 key 的值变化,则保存
300 秒内如果至少有 10 个 key 的值变化,则保存
60 秒内如果至少有 10000 个 key 的值变化,则保存
 
save 900 1
save 300 10
save 60 10000

监听端口号,默认为 6379,如果你设为 0 ,redis 将不在 socket 上监听任何客户端连接。
port 6379

Redis默认只允许本地连接,不允许其他机器连接
bind 127.0.0.1

更多配置文件:https://www.cnblogs.com/kreo/p/4423362.html

Redis数据库简单使用

DBSIZE      查看当前数据库的key数量
keys *      查看key的内容
FLUSHDB     清空当前数据库的key的数量
FLUSHALL    清空所有库的key(慎用)
exists key   判断key是否存在

redis常用五大数据类型

1.redis-string

string是redis最基本的类型,一个key对应一个value
在这里插入图片描述
string可以包含任何数据,最大不能超过512M
1.set/get/del/append/strlen

set  ---- 设置值
get  ---- 获取值
mset  ---- 设置多个值
mget  ---- 获取多个值
append ---- 添加字段
del ---- 删除
strlen ---- 返回字符串长度

2.incr/decr/incrby/decrby

incr ---- 增加
decr ---- 减少
incrby  ----- 制定增加多少
decrby  ----- 制定减少多少

3.getrange/setrange

getrange ---- 获取指定区间范围内的值,类似between....and的关系
setrange ---- 代表从第几位开始替换,下脚本从零开始
从0 -1表示全部
2.redis-list(单值多value)

List(列表)
列表是简单的字符串列表,按照插入顺序排序,可以添加一个元素列表的头部(左边)或者尾部(右边)
它的底层实际是个链表
在这里插入图片描述
1.lpush/rpush/lrange

lpush/rpush/lrange ---- 从左/从右/获取指定长度
lpush list01  1 2 3 4 5  倒序排列
rpush list02  1 2 3 4 5  正序排列
lrange  list01  0  -1  获取list01 中的所有值

2.lpop/rpop

lpop/rpop ---- 移除最左/最右
lpop list01 删除元素5
rpop list01 删除元素1

3.lindex,按照索引下标获得元素(从上到下)

lrange list01 0 -1
lindex list01 1

4.llen,求列表长度

llen list01

5.lrem key

删N个value
lrem list01 2 1   在list01中删除21

6.ltrim key

ltrim ---- 开始index结束index,截取指定范围的值后在赋值给key
ltrim list01 0 2    截取list01 从02的数据在赋值给list01

7.rpoplpush list1 list2 将list1中最后一个压入list2中第一位

lrange list01 0 -1
lrange list02 0 -1
rpoplpush list1 list2

8.lset key index value

lset list01 0 x     将list02中第一位换成x

9.linsert key before/after

linsert list01b  before x php  在x之前加字段php
3.redis-Hash

hash是一个键值对集合
hash是一个string类型的field和value的映射表,hash特别适合存储对象
在这里插入图片描述
1.hset/hget/hmset/hmget/hgetall/hdel

设值/取值/设值多个值/取多个值/取全部值/删除值
hset user id 11
hget user id 
hmset customer id 11 name juran age 26
hmget customer id name age      只返回相应的值
hgetall   customer              返回全部
hdel user id   删除id

2.hlen

求哈希长度 
hlen customer

3.hexists key

hexists ---- 在key里面的某个值
存在返回1 ,不存在返回0

4.hkeys/hvals

hkeys students
hvals students
4.redis-set(不重复的)

Set(集合)
set是string类型的无序集合
在这里插入图片描述
1.sadd/smembers/sismember

sadd/smembers/sismember ---- 添加/查看集合/查看是否存在
sadd set01 1 2 2 3 3  去掉重复添加
smembers set01   得到set01
sismember set01 1  如果存在返回1  不存在返回0

2.scard

scard ---- 获取集合里面的元素个数
scard set01

3.srem key value

srem ---- 删除集合中元素
srem set01 3
SMEMBERS set01   3已经被删除掉

4.srandmember key

srandmembe ---- 随机出几个数
sadd set02  1 2 3 4 5 6 7 8
srandmember set02  2

5.spop key

spop ---- 随机出栈
spop set01

6.smove key1 key2

sadd set03 x y z 
smove set01 set03 2  将set01中的2 移动到set03中

7.数学集合类

sadd set01 1 2 3 4 5
sadd set02 1 2 3 a b
差集
SDIFF set01 set02   返回 4 5 在第一个set中不在第二个set中
交集
SINTER set01 set02   返回 1 2 3
并集
SUNION set01 set02  返回set01 set02 中的值  去掉重复
5.redis-Zset

Zset(有序集合)

在这里插入图片描述
1.zadd/zrange

zadd zset01 60 v1 70 v2 80 v3 90 v4 100 v5
zrange zset01 0 -1 
带分数返回   withscores

2.zrangebyscore key start end

zrangebyscore key start end----根据开始结束来取值
zrangebyscore zset01 60 70
zrangebyscore zset01 60 (90   表示不包含90
zrangebyscore zset01  60 90  limit  1 2 从第一条开始截取2

3.zrem key

zrem key value---- 某score下对应的value值,作用是删除元素
zrem zset01 v1

4.zcard/zcount key score 区间/zrank key values

zcard   求zset01 总条数
zcount  zset01 60 9060-90个数
zrank   zset01  v2   返回1  返回对应下角标,从0开始

Python操作Redis

redispy安装及连接

安装

pip install redis

连接

r = redis.StrictRedis(host='localhost',port=6379,db=0)

字符串相关操作

import redis

class TestString(object):
	def __init__(self):
        self.r = redis.StrictRedis(host='192.168.75.130',port=6379)
    设置值
    def test_set(self):
        res = self.r.set('user1','juran-1')
        print(res)
    取值
	def test_get(self):
        res = self.r.get('user1')
        print(res)
    设置多个值
    def test_mset(self):
        d = {
            'user2':'juran-2',
            'user3':'juran-3'
        }
        res = self.r.mset(d)
    取多个值
    def test_mget(self):
        l = ['user2','user3']
        res = self.r.mget(l)
        print(res)
    删除
	def test_del(self):
        self.r.delete('user2')

列表相关操作

class TestList(object):
    def __init__(self):
        self.r = redis.StrictRedis(host='192.168.75.130',port=6379)
	插入记录
    def test_push(self):
        res = self.r.lpush('common','1')
        res = self.r.rpush('common','2')
        # res = self.r.rpush('jr','123')
	弹出记录
    def test_pop(self):
        res = self.r.lpop('common')
        res = self.r.rpop('common')
	范围取值
    def test_range(self):
        res = self.r.lrange('common',0,-1)
        print(res)

集合相关操作

class TestSet(object):
    def __init__(self):
        self.r = redis.StrictRedis(host='192.168.75.130', port=6379)
	添加数据
    def test_sadd(self):
        res = self.r.sadd('set01','1','2')
        lis = ['Cat','Dog']
        res = self.r.sadd('set02',lis)
	删除数据
    def test_del(self):
        res = self.r.srem('set01',1)
	随机删除数据
    def test_pop(self):
        res = self.r.spop('set02')

哈希相关操作

class TestHash(object):
    def __init__(self):
        self.r = redis.StrictRedis(host='192.168.75.130', port=6379)
	
	批量设值
    def test_hset(self):
        dic = {
            'id':1,
            'name':'huawei'
        }
        res = self.r.hmset('mobile',dic)
	批量取值
    def test_hgetall(self):
        res = self.r.hgetall('mobile')
	判断是否存在	存在返回1  不存在返回0
    def test_hexists(self):
        res = self.r.hexists('mobile','id')
        print(res)

Scrapy-分布式

什么是scrapy_redis

scrapy_redis:Redis-based components for scrapy

github地址:https://github.com/rmax/scrapy-redis

回顾scrapy工作流程
在这里插入图片描述
scrapy_redis工作流程
在这里插入图片描述
scrapy_redis下载

clone github scrapy_redis源码文件
git clone https://github.com/rolando/scrapy-redis.git

scrapy_redis中的settings文件

# Scrapy settings for example project
#
# For simplicity, this file contains only the most important settings by
# default. All the other settings are documented here:
#
#     http://doc.scrapy.org/topics/settings.html
#
SPIDER_MODULES = ['example.spiders']
NEWSPIDER_MODULE = 'example.spiders'

USER_AGENT = 'scrapy-redis (+https://github.com/rolando/scrapy-redis)'

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"    # 指定那个去重方法给request对象去重
SCHEDULER = "scrapy_redis.scheduler.Scheduler"    # 指定Scheduler队列
SCHEDULER_PERSIST = True        # 队列中的内容是否持久保存,为false的时候在关闭Redis的时候,清空Redis
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,    # scrapy_redis实现的items保存到redis的pipline
}

LOG_LEVEL = 'DEBUG'

# Introduce an artifical delay to make use of parallelism. to speed up the
# crawl.
DOWNLOAD_DELAY = 1

scrapy_redis运行

allowed_domains = ['dmoztools.net']
start_urls = ['http://www.dmoztools.net/']

scrapy crawl dmoz

运行结束后redis中多了三个键

dmoz:requests   存放的是待爬取的requests对象 
dmoz:item       爬取到的信息
dmoz:dupefilter 爬取的requests的指纹

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值