前戏:
1.你是否在夜深人静的时候,想看一些会让你更睡不着的图片却苦于没有资源..
2.你是否在节假日出行高峰的时候,想快速抢购火车票成功...
3.你是否在网上购物的时候,想快速且精准的定位到口碑质量最好的商品..
什么是爬虫:
通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。
爬虫的价值:
实际应用
就业
爬虫究竟是合法还是违法的?
在法律中是不被禁止
具有违法风险
善意爬虫恶意爬虫
爬虫带来的风险可以体现在如下2方面:
爬虫干扰了被访问网站的正常运营
爬虫抓取了收到法律保护的特定类型的数据或信息
如何在使用编写爬虫的过程中避免进入局子的厄运呢?
时常的优化自己的程序,避免干扰被访问网站的正常运行
在使用,传播爬取到的数据时,审查抓取到的内容,如果发现了涉及到用户隐私、商业机密等敏感内容需要及时停止爬取或传播
爬虫在使用场景中的分类
通用爬虫:
抓取系统重要组成部分。抓取的是一整张页面数据 。
聚焦爬虫:
是建立在通用爬虫的基础之上。抓取的是页面中特定的局部内容。
增量式爬虫:
检测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。
反爬机制
门户 网站可以通过制定相应的策略或者技术手段, 防止爬虫程序进行网站数据的爬取。
反反爬策略
爬虫程序可以通过制定相关的策略或者技术手段,破解门]户网站中具备的反爬机制,从而可以获取户网站中具备的反爬机制,从而可以获取门户网站中相关的数据。
robots. txt协议:
君子协议。规定了网站中哪些数据可以被爬虫爬取哪些数据不可以被爬取。
http协议
概念:就是服务器和客户端进行数据交互的一种形式。
常用请求头信息
User-Agent:请求载体的身份标识
Connection:请求完毕后,是断开连接还是保持连接
常用响应头信息
Content-Type:服务器响应回客户端的数据类型
https协议:
安全的超文本传输协议
加密方式
对称秘钥加密
客户端向服务器发送一条信息,首先客户端会采用已知的算法对信息进行加密,比如MD5或者Base64加密,接收端对加密的信息进行解密的时候需要用到密钥,
中间会传递密钥,(加密和解密的密钥是同一个),密钥在传输中间是被加密的。这种方式看起来安全,但是仍有潜在的危险,一旦被窃听,或者信息被挟持,
就有可能破解密钥,而破解其中的信息。因此“共享密钥加密”这种方式存在安全隐患。
非对称秘钥加密
“非对称加密”使用的时候有两把锁,一把叫做“私有密钥”,一把是“公开密钥”,使用非对象加密的加密方式的时候,服务器首先告诉客户端按照自己给定的公开密钥进行加密处理,
客户端按照公开密钥加密以后,服务器接受到信息再通过自己的私有密钥进行解密,这样做的好处就是解密的钥匙根本就不会进行传输,因此也就避免了被挟持的风险。
就算公开密钥被窃听者拿到了,它也很难进行解密,因为解密过程是对离散对数求值,这可不是轻而易举就能做到的事。
但是非对称秘钥加密技术也存在如下缺点:
第一个是:如何保证接收端向发送端发出公开秘钥的时候,发送端确保收到的是预先要发送的,而不会被挟持。只要是发送密钥,就有可能有被挟持的风险。
第二个是:非对称加密的方式效率比较低,它处理起来更为复杂,通信过程中使用就有一定的效率问题而影响通信速度
证书秘钥加密
在上面我们讲了非对称加密的缺点,其中第一个就是公钥很可能存在被挟持的情况,无法保证客户端收到的公开密钥就是服务器发行的公开密钥。此时就引出了公开密钥证书机制。数字证书认证机构是客户端与服务器都可信赖的第三方机构。证书的具体传播过程如下:
服务器的开发者携带公开密钥,向数字证书认证机构提出公开密钥的申请,数字证书认证机构在认清申请者的身份,审核通过以后,会对开发者申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将密钥放在证书里面,绑定在一起
服务器将这份数字证书发送给客户端,因为客户端也认可证书机构,客户端可以通过数字证书中的数字签名来验证公钥的真伪,来确保服务器传过来的公开密钥是真实的。一般情况下,证书的数字签名是很难被伪造的,这取决于认证机构的公信力。一旦确认信息无误之后,客户端就会通过公钥对报文进行加密发送,服务器接收到以后用自己的私钥进行解密。
requests模块
urllib模块
requests模块
python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高。
作用:
模拟浏览器发请求。
如何使用: (requests模块的编码流程)
指定url
发起请求
获取响应数据
持久化存储
环境安装:
pip install requests
实战编码:
需求:爬取搜狗首页的页面数据
代码:
import requests
if __name__ == '__main__':
# 指定URL
url = "https://www.sogou.com/"
# 发起请求,返回一个响应对象
response = requests.get(url=url)
# 获取响应数据,返回的是一个字符串类型的响应数据
page_text = response.text
# 持久化存储
with open("sogou.html","w",encoding="utf-8") as f:
f.write(page_text)
print("爬取数据结束!")
实战巩固
-需求:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
爬取指定词条的整个网页
UA检测
UA伪装
-需求:破解百度翻译
爬取需要翻译内容的ajax的响应
从网页的检查窗口的network中的XHR中可以看到ajax发送的请求,我们要做的就是模仿ajax向服务器发送请求,接收数据
post请求(携带了数据data)(需要翻译的内容)
响应的数据是json类型
-需求:爬取豆瓣电影分类排行榜https://movie.douban.com/中的电影详情数据
爬取某一部分电影的ajax的响应
get请求(携带了参数param)(从哪一部电影开始,一次请求多少个电影)
响应的数据是json类型
-需求:爬取肯德基餐厅查询http://www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数据
-需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据http://125.35.6.84:81/xk/
http://scxk.nmpa.gov.cn:81/xk/
-动态加载数据
-首页中对应的企业信息数据是通过ajax动态请求到的。
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList
-通过对详情页url的观察发现:
- url的域名都是一样的,只有携带的参数(id)不一样
-id值可以从首页对应的ajax请求到的json中获取
- 域名和id值可以拼接成对应完整企业详情页的url
-详情页的企业详情数据也是动态加载出来的
- http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
-观察后发现
- 所有的post请求的url都是一样的,只有参数id值是不同。
- 如果我们可以批量获取多家企业的id后,就可以将id和url形成一个完整的详情页对应详情页的url
聚焦爬虫:爬取页面中指定的页面内容。
- 编码流程:
- 指定url
- 发起请求
- 获取响应数据
- 数据解析
- 持久化存储
数据解析分类:
- 正则
- bs4
- xpath (***)
数据解析原理概述:
- 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
- 1.进行指定标签的定位
- 2.标签或者标签对应的属性中存储的数据值进行提取(解析)
正则解析
bs4进行数据解析
数据解析的原理:
-1.标签定位
-2.提取标签、标签属性中存储的数据值
bs4数据解析的原理:
-1 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
-2 通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
需要安装:pip install bs4
bs4在使用时候需要—个第三方库,把这个库也安装一下
pip install lxml
如果下载失败,或下载速度极慢,建议把pip源改为国内源,阿里源、豆瓣源、网易源等
- windows
(1)打开文件资源管理器(文件夹地址栏中)
(2)地址栏上面输入%appdata%
(3)在这里面新建一个文件夹pip
(4)在pip文件夹里面新建一个文件叫做pip.ini,内容写如下即可
[global]
timeout = 6000
index-url = https://mirrors.aliyun.com/pypi/simple/
trusted-host = mirrors.aliyun.com
- Linux
(1) cd ~
(2) mkdir -/-pip
(3) vi -/ -pip/pip.conf
(4)编辑内容和windows—模—样
如何实例化一个BeautifulSoup对象呢?
# 导包
from bs4 import BeautifulSoup
1.将本地的html文档中的数据加载到该对象中
f = open("sogou.html","r",encoding="utf-8")
soup = BeautifulSoup(f, "lxml")
2.将互联网上获取的页面源码加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text, 'lxml')
3.soup的方法有哪些?
soup.Tagname,比如:soup.a soup.p
返回的是html中第一次出现的Tagname标签
soup.find():
find('tagName'):等同于soup.div
属性定位:
soup. find( 'div', class_/id/attr='song')
soup.find_all('tagName'):返回符合要求的所有标签(列表)
也可以进行数据定位
soup.select():
soup.select( '某种选择器(id, class,标签.. .选择器) ' ) ,返回的是个列表。
层级选择器:
soup.select(".tang > ul > li > a"): 大于号表示的是一个层级
soup.select(".tang > ul a"):空格表示的多个层级
4.获取标签之间的文本数据:
soup.a.text/string/get_text()
text/get_text():可以获取某一个标签中所有的文本内容(子子孙孙)
string:只可以获取该标签下面直系的文本内容(儿子)
5.获取标签中属性值:
soup.a["href"]
xpath解析:最常用且最便捷高效的一种解析方式。通用性。
xpath解析原理:
1.实例化一个et ree的对象,且需要将被解析的页面源码数据加载到该对象中。
2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
环境的安装:
pip install lxml
如何实例化一个etree对象:from lxml import etree
1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath)
2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML('page_text')
3.xpath("xpath表达式")
xpath表达式:
/: 表示的是从根节点开始定位。表示的是个层级。
//: 表示的是多个层级。可以表示从任意位置开始定位。
属性定位: //div[@class='song'] ——> tag[@att rName=" attrValue"]
索引定位: //div[@class="song"]/p[3] 索引是从1开始的。
取文本:
/text()获取的是标签中直系的文本内容
//text()标签中非直系的文本内容(所有的文本内容)
取属性:
/@attrName ==> img/@src
验证码识别
反爬机制:
验证码.识别验证码图片中的数据,用于模拟登陆操作。
识别验证码的操作:
人工肉眼识别。(不推荐)
第三方自动识别(推荐)
超级鹰: https://www.chaojiying.com/
超级鹰的使用流程:
注册用户
登录:查询该用户是否还有剩余的题分
创建一个软件:用户中心 -> 软件ID -> 新建一个软件 -> 提交(软件id和秘钥)
下载示例代码:开发文档-> Python示例下载
实战:识别古诗文网登录页面中的验证码。
使用打码平台识别验证码的编码流程:
将验证码图片进行本地下载
调用平台提供的示例代码进行图片数据识别
模拟登录:
爬取基于某些用户的用户信息。
需求:对人人网进行模拟登录。
点击登录按钮之后会发起一个post请求
post请求中会携带登录之前录入的相关的登录信息(用户名,密码,验证码......)
验证码:每次请求都会变化
http/https协议特性:无状态。
没有请求到对应页面数据的原因:
发起的第二次基于个人主页页面请求的时候,服务器端并不知道该此请求是基于登录状态下的请求。
cookie:用来让服务器端记录客户端的相关状态。
手动处理:通过抓包工具获取cookie值,将该值封装到headers中。(不建议)
自动处理:
cookie值的来源是哪里?
模拟登录post请求后,由服务器端创建。
session会话对象:
作用:
1.可以进行请求的发送。
2.如果请求过程中产生了cookie,则该cook ie会被自动存储/携带在该session对象中
创建一个sess ion对象: session=requests.Session()
使用session对象进行模拟登录post请求的发送(cookie就会被存储在session中)
session对象对个人主页对应的get请求进行发送(携带了cookie)
代理:破解封IP这种反爬机制。
什么是代理:
代理服务器。
反爬机制:封ip
反反爬策略:使用代理进行请求发送
代理的作用:
突破自身IP访问的限制。
隐藏自身真实IP
代理相关的网站:
快代理
西祠代理
www.goubanjia.com
代理ip的类型:
http:应用到http协议对应的urL中
https:应用到ht tps协议对应的ur1中
代理ip的匿名度:
透明:服务器知道该次请求使用了代理,也知道请求对应的真实ip
匿名:知道使用了代理,不知道真实ip
高匿:不知道使用了代理,更不知道真实的ip
高性能异步爬虫
目的:在爬虫中使用异步实现高性能的数据爬取操作。
异步爬虫的方式:
多线程,多进程(不建议) :
好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行。
弊端:无法无限制的开启多线程或者多进程。
线程池、进程池:(适当的使用)
导包:from multiprocessing.dummy import Pool
好处:我们可以降低系统对进程或者线程创建和销毁的频率,从而很好的降低系统的开销。
弊端:池中线程或进程的数量是有上限。
实例:爬取梨视频中的视频
单线程+异步协程(推荐) :
event_ Loop:
事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执行。
coroutine:
协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。
我们可以使用async关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返一个协程对象。
task:
任务,它是对协程对象的进一步封装, 包含了任务的各个状态。
future:
代表将来执行或还没有执行的任务,实际上和task 没有本质区别。
async:
定义一个协程.
await:
用来挂起阻塞方法的执行。
selenium模块的基本使用
问题:selenium模块和爬虫之间具有怎样的关联?
便捷的获取网站中动态加载的数据
便捷实现模拟登录
什么是selenium模块?
基于浏览器自动化的一个模块。
selenium使用流程:
环境安装:
pip install selenium
下载一个浏览器的驱动程序(谷歌浏览器)
下载路径:http://chromedriver.storage.googleapis.com/index.html
驱动程序和浏览器的映射关系:http://blog.csdn.net/huilan_same/article/details/51896672
导包:
from selenium import webdriver
实例化一个浏览器对象:
bro = webdriver.Chrome(executable_path="./chromedriver.exe")
编写基于浏览器自动化的操作代码
发起请求:get(url)
标签定位:find系列的方法
标签交互:send_keys( 'xx')
执行js程序:excute_script('jsCode')
前进,后退:back(),forward()
关闭浏览器:quit()
实例1、爬取药监局化妆品企业(ajax动态生成的)
实例2、爬取淘宝首页,模拟输入要搜索的商品,和往下滑动滚轮
selenium处理iframe
如果定位的标签存在于iframe标签之中,则必须使用switch_to.frame(id)
动作链(拖动):from selenium.webdriver import ActionChains
实例化一个动作链对象:action = ActionChains(bro)
click_and_hold (div):长按且点击操作
move_by_offset(x,y)
perform()让动作链立即执行
action.release()释放动作链对象
实例:拖动iframe中的元素的位置
综合实例:
模拟QQ空间登陆
无可视化界面(无头浏览器):from selenium.webdriver.chrome.options import Options
#实现无可视化界面的操作
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
使用方法:
bro = webdriver.Chrome(executable_path='./chromedriver.exe',chrome_options=chrome_options)
规避风险:from selenium.webdriver import ChromeOptions
#实现规避检测
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
使用方法:
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)
综合实例:12306模拟登录
超级鹰:http://www.chaojiying.com/about.html
注册:普通用户
登录:普通用户
题分查询:充值
创建一个软件(id)
下载示例代码
12306模拟登录编码流程:
使用selenium打开登录页面
对当前selenium打开的这张页面进行截图
对当前图片局部区域(验证码图片)进行裁剪
# 踩坑:要把电脑的分辨率调成100%,才可以准确的截取到验证码的图
好处:将验证码图片和模拟登录进行一一对应。
使用超级鹰识别验证码图片(坐标)
scrapy框架
什么是框架?
就是一个集成了很多功能并且具有很强通用性的一个项目模板。
如何学习框架?
专学习框架封装的各种功能的详细用法。
什么是scrapy?
爬虫中封装好的一个明星框架。功能:高性能的持久化存储,异步的数据下载,高性能的数据解析,分布式
scrapy框架的基本使用
环境的安装:
mac or linux:pip install scrapy
windows:
pip install wheel
下载twisted,下载地址为http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
安装twisted: pip install Twisted-17.1.0-cp36-cp36m-win_amd64.whl
pip install pywin32
pip install scrapy
测试:在终端里录入scrapy指令,没有报错即表示安装成功!
创建一个工程:scrapy startproject xxxPro
cd xxxPro
在spiders子目录中创建一个爬虫文件
scrapy genspider spiderName www.xxx.com
执行工程:
scrapy crawl spiderName
默认输出结果中带有所有的日志信息
可以使用:scrapy crawl spiderName --nolog
来不让日志信息显示,但是这样的话,如果出错了,错误信息也将不会显示
推荐:在settings文件中,加上一句:LOG_LEVEL = "ERROR" # 显示指定类型的日志信息
创建项目后,要在settings中做的事:
# UA伪装
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
# 是否遵从ROBOTSTXT协议
ROBOTSTXT_OBEY = False
# 显示指定类型的日志信息
LOG_LEVEL = "ERROR"
数据的解析:
# xpath 返回的是一个列表,但是列表中的元素是一个Selector的对象
# extract()能够把Selector对象中的data数据提取出来
# 如果列表调用了.extract()方法,则表示,将列表中每一个Selector对象的data的值取出,放在列表中
持久化存储
基于终端指令:scrapy crawl 【spiderName】 -o 【filepath】
要求:只可以将parse方法的返回值存储到本地的文本文件中
注意:持久化存储对应的文本文件的类型只可以为:'json','jsonlines','jl','csv','xml','marshal','pickle'.
好处:简介高效便捷
缺点:局限性比较强(数据只可以存储到指定后缀的文本文件中)
基于管道:
编码流程:
数据解析
在item类中定义相关的属性
将解析的数据封装存储到item类型的对象
将item类型的对象提交给管道进行持久化存储的操作
在管道类的process_item中要将其接受到的item对象中存储的数据进行持久化存储操作
在配置文件中开启管道 在配置文件中把下面代码的注释去掉
ITEM_PIPELINES = {
'first.pipelines.FirstPipeline': 300,
}
好处:
通用性强,既可以存在本地文件,又可以存到数据库等
面试题:将爬取到的数据一份存储到本地一份存储到数据库,如何实现?
【注】
管道文件中一个管道类对应的是将数据存储到一种平台
爬虫文件提交的item只会给管道文件中第一个被执行的管道类接受
process_item中的return item表示将item传递给下一个即将被执行的管道类
基于Spider的全站数据爬取
就是将网站中某板块下的全部页码对应的页面数据进行爬取
需求:爬取校花网中的照片的名称
实现方式:
将所有页面的url添加到start_urls列表(不推荐)
自行手动进行请求发送(推荐)
手动请求发送:
yield scrapy.Request(url,callback):callback专门用做于数据解析
调试的时候,发现回调函数 parse_detail 没有被调用,这可能就是被过滤掉了,
两种方法能够使 requests 不被过滤:
1. 在 allowed_domains 中加入 url
2. 在 scrapy.Request() 函数中将参数 dont_filter=True 设置为 True
scrapy五大核心组件简介
引擎(Scrapy)
用来处理整个系统的数据流处理, 触发事务(框架核心)
调度器(Scheduler)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回.
可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader)
用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders)
爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。
用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline)
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。
当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
请求传参
使用场景:如果爬取解析的数据不在同一张页面中。(深度爬取)
需求:爬取boss的岗位名称,岗位描述
图片数据爬取之ImagesPipeline
基于scrapy爬取字符串类型的数据和爬取图片类型的数据区别?
字符串:只需要基于xpath进行解析且提交管道进行持久化存储
图片:xpath解析出图片src的属性值。单独的对图片地址发起请求获取图片二进制类型的数据
ImagesPipeline:
只需要将img的src的属性值进行解析,提交到管道,管道就会对图片的src进行请求发送获取图片的二进制数据,并会进行持久化储存
需求:爬取站长素材中的高清图片
使用流程:
数据解析(图片的地址)
将存储图片地址的item提交到制定的管道类
在管道文件中自定制一个基于ImagesPipeLine的一个管道类,重写以下方法:
get_media_request
file_path
item completed
在配置文件中:
指定图片存储的目录:IMAGES_STORE = './imgs bobo'
指定开启的管道:自定制的管道类
中间件
下载中间件
位置:引擎和下载器之间
作用:批量拦截到整个工程中所有的请求和响应
拦截请求:
UA伪装:process_request
代理IP:process_exception: return request
拦截响应:
篡改响应数据,响应对象,用selenium爬取动态加载的数据
需求:爬取网易新闻中的新闻数据(标题和内容)
1.通过网易新闻的首页解析出五大板块对应的详情页的url(没有动态加载)
2.每一个桐决对应的新闻标题都是动态加载出来的(动态加载)
3.通过解析出每一条新闻详情贡的url获取详情页的页面源码,解析出新闻内容
crawlSpider:类,Spider的一个子类
全站数据爬取的方式
基于Spider:手动请求
基于CrawlSpider
CrawlSpider的使用:
创建一个工程
cd xxx
创建爬虫文件(CrawlSpider):
scrapy genspider -t crawl xxx www.xxx.com
链接提取器:
作用:根据指定的规则(allow)进行指定链接的提取
规则解析器:
作用:将链接提取器提取到的链接进行指定规则(callback)的解析
分布式爬虫
概念:我们需要搭建一个分布式的机群,让其对一组资源进行分布联合爬取。
作用:提升爬取数据的效率
如何实现分布式?
安装一个scrapy-redis的组件
原生的scarapy是不可以实现分布式爬虫,必须要让scrapy结合着scrapy-redis组件一起实现分布式爬虫
为什么原生的scrapy不可以实现分布式?
调度器不可以被分布式机群共享
管道不可以被分布式机群共享
scrapy-redis组件作用:
可以给原生的scrapy框架提供可以被共享的管道和调度器
实现流程
创建一个工程
创建—个基于CrawlSpider的爬虫文件scrapy genspider -t crawl xxx www.xxx.com
修改当前的爬虫文件:
导包:from scrapy_redis.spiders import RedisCrawlSpider
将start_urls和allowed_domains进行注释
添加一个新属性:redis_key ='sun' # 可以被共享的调度器队列的名称
编写数据解析相关的操作
将当前爬虫类的父类修改成 RedisCrawlSpider
修改配置文件settings
指定使用可以被共享的管道:
ITEM_PIPELINES ={
'scrapy_redis.pipelines.RedisPipeline':400
}
指定调度器:
#增加了一个去重容器类的配置,作用使用Redis的set集合来存储请求的指纹数据,从而实现数据去重的持久化存储
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
#使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#配置调度器是否要持久化,也就是当爬虫结束了,要不要清空Redis中请求队列和去重指纹的set,如果是True将接着爬取,不清空
SCHEDULER_PERSIST = True
指定redis服务器:
#指定redis
REDIS_HOST = '127.0.0.1' #redis远程服务器的ip
REDIS_PORT = 6379 #端口号
redis相关操作配置:
配置redis的配置文件:
linux或者mac: redis.conf
windows:redis.windows.conf
打开配置文件修改:
将bind 127.0.0.1进行删除
关闭保护模式:protected-mode yes改为no
结合着配置文件开启redis服务
redis-server 配置文件
启动客户端:
redis-cli
执行工程:
scrapy runspider xxx.py(爬虫文件的名字)
向调度器的队列中放入一个起始的url:
调度器的队列在redis的客户端中
lpush xxx(被共享的调度器队列的名称) www.xxx.com(起始url)
爬取到的数据存储在了redis的proName:items这个数据结构中
增量式爬虫
概念:监测网站数据更新的情况,只会爬取网站最新更新出来的数据。
分析:
指定一个起始url
基于CrawlSpider获取其他页码链接
基子Rule将其他页码链接进行请求
从每一个页码对应的页面源码中解析出每一个电影详情页的URL
核心:检测电影详情页的url之前有没有请求过
将爬取的电影详情页的url存储
存储至redis的set数据结构,如果已经存在的url再往set中存,会返回0,如果是第一次存就返回1。
如果是1,就对该url进行爬取,否则不进行爬取
对详情页的url发起请求,然后解析出电影的名称和简介
进行持久化存储