爬虫(下)
--scrapy框架
一、基础学习
1、scrapy框架示意图
2、scrapy框架安装和学习文档
安装:pip install scrapy
注:
(1)在ubantu上安装scrapy之前,需要先安装一下依赖:
sudo apt-get install python -dev python-pip libxml12-dev libxslt1-dev zlibig-dev libffi-dev libss1-dev,然后在通过pip install scrapy安装
(2)在windows系统下,提示这个错误ModelNotFoundError:No module.... "win32api"
安装解决:pip install pywin32
(3)中文文档: http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html
3、使用步骤
(1)创建项目
使用命令:scrapy startproject 项目名称
项目结构说明
items.py:用来存放爬虫爬取下来数据的模型
middlewares.py:用来存放各种中间件的文件
pipelines.py:用来将items.py的模型存储到本地磁盘
settings.py:爬虫的一些配置信息(比如请求头、多久发送一次请求、ip代理等)
spiders包里面;存放所有的爬虫
scrapy.cfg:scrapy的项目配置文件(2)创建一个爬虫
创建一个爬虫。并且能爬取的网页只会限制在www.qiushibaike.com这个域名下,www.部分可以不写
使用命令:scrapy genspider qsbk_spider "qiushibaike.com"
注意:先进入项目中spiders里面,在执行命令,保证爬虫的代码在spiders包里面
创建的爬虫文件说明
爬虫类必须继承scrapy.Spider类
类属性说明
name:表示爬虫的名字,有多个爬虫的话,名字必须唯一
allowed_domains:允许爬虫爬取域名的范围
start_urls:开始爬取的位置
类方法说明
parse():爬取到数据以后。自动执行parse,响应相关信息保存在response里面
response:是一个HttpResponse类型(3)配置settings.py文件
推荐配置
ROBOTSTXT_OBEY = True:设置为False
DEFAULT_REQUEST_HEADERS:设置请求头,打开注释并添加:User-Agent请求头,伪装成浏览器
DOWNLOAD_DELAY:下载延迟时间1s,防止把服务器弄奔溃,DOWNLOAD_DELAY = 1(4)items.py定义爬虫文件返回数据格式
class QsbkDownloadItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() dz_content = scrapy.Field() dz_jokes = scrapy.Field() dz_url = scrapy.Field()
(5)爬虫文件里面parse()方法里面处理数据
- response对象属性和方法,<class 'scrapy.http.response.html.HtmlResponse'>,方法:xpath(),支持利用xpath获取数据。
- 处理好以后以yield迭代器的方式给pipelines.py,yield数据items.py里面定义类的类型,也可以把每一项放在一个列表中一起return返回, 就不使用yield。
- 爬取多个页面,使用scrapy.Request(url, callback)再次发起请求,url:发送请求的url页面,callbake:响应回来处理数据的函数,其实就是parse()函数
class QsbkDzSpiderSpider(scrapy.Spider): name = 'qsbk_dz_spider' allowed_domains = ['qiushibaike.com'] start_urls = ['https://www.qiushibaike.com/text/page/1/'] def parse(self, response): dz_contents = response.xpath("//*[@id='content']/div/div[2]/div") for dz in dz_contents: #段子内容 dz_con = dz.xpath(".//div[@class='content']//span[1]/text()").getall() dz_content = "".join(dz_con).strip() # print(dz_content) #段子好笑数 dz_jokes = dz.xpath(".//span[@class='stats-vote']/i/text()").get().strip() # print(dz_jokes) #完整段子url dz_url = dz.xpath(".//a[@class='contentHerf']/@href").get().strip() yield QsbkDownloadItem(dz_content =dz_content, dz_jokes=dz_jokes, dz_url=dz_url)
(6)pipelines.py存储数据
主要三个方法:
open_spider(self, spider):可使用__init__()方法代替,爬虫打开后自动调用,一般用于打开文件
process_item(self,item,spider):爬虫传递过来数据时自动调用(即执行了yield)
把数据传递给item参数,一般用于写入文件
close_spider(self, spider):爬虫关闭后自动调用,一般用于关闭文件配置settings.py自动调用pipelines:打开注释ITEM_PIPLINES,字典里面,key代表pipline的位置,value:代表执行pipline优先级,值越小越高
用JsonItemExporter自动导出数据:
使用步骤:
导入JsonItemExporter类
from scrapy.exporters import JsonItemExporter
创建JsonItemExporter(fp, ensure_ascii=False,encoding="utf-8")对象
开始导出,JsonItemExporter对象的start_exporting()方法
导出数据,JsonItemExporter对象的export_item(item)方法
结束导出, sonItemExporter对象的finish_eexporting(),注:放在关闭文件前
这个类是每次把数据添加到内存中,最后统一写入磁盘。好处是存储的数据是一个满足json数据格式规则的数据。坏处是如果数据量过大,那么比较耗内存。
用JsonLinesExporter自动导出数据:
与使用方式sonItemExporter类似,但是不用写开始与结束
存储数据格式为,每个字典为一行,没有[]括起来
这个类是每次调用export_item,就把数据存储到硬盘中。坏处是每个字典是一行,整个文件不是满足json格式的文件,好处不耗内存,数据也比较安全class QsbkDownloadPipeline: def __init__(self): self.fp = open("dz_joke.json", "wb") self.exp = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding="utf-8") def process_item(self, item, spider): self.exp.export_item(item) return item def close_spider(self, spider): self.fp.close()
(7)执行爬虫
方式一:直接终端输入命令
命令:scrapy crawl 爬虫名字
注:先进入虚拟环境,项目中,在执行命令
方式二:在python中使用命令,运行该.py文件
创建一个.py文件,名字任意
导入cmdline
from scrapy import cmdline
execute执行命令:cmdline.execute("scrapy crawl 爬虫名字".split())
等价于:cmdline.execute(["scrapy", "crawl", "爬虫名字"])from scrapy import cmdline cmdline.execute("scrapy crawl qsbk_dz_spider".split())
(8)总结
- 创建项目,创建一个爬虫
- 配置settings.py文件
- items.py定义爬虫文件返回数据格式
- 爬虫处理response后按照items.py定义的数据格式返回数据
- pipelines.py导出爬取的数据,用JsonItemExporter自动导出数据,用JsonLinesExporter自动导出数据
Scrapy Shell
我们想要在爬虫中使用xpath,beautifulsoup,正则表达式、css选择器等来提取想要的数据。但是因为scrapy是一个比较重的框架。每次运行起来都要等待一段时间。因此要去验证我们写的提取规则是否正确,是一个比较麻烦的事情。因此Scrapy提供了一个shell,用于方便测试。
打开终端进入到scrapy所在的目录,然后进入scrapy框架所在虚拟环境中
输入命令:scrapy shell url链接
就会进入到scrapy的shell环境中,就可以像在爬虫中使用parse()方法中一样使用
二、CrawlSpider爬虫
想要只要遇到满足某个条件的url,都给我进行爬取,那么就可以通过CrawlSpider实现,CrawlSpider继承自Spider,添加了新功能,可以自定义爬取的url规则,只要碰到满足条件的url自动进行爬取,不用手动yield Request。
LinkExtractors链接提取器:LinkExtractors类,自动提取满足规则的url,配合Rule规则类使用。
使用步骤:
1、创建CrawlSpider爬虫
scrapy genspider -t crawl 爬虫名字 域名
爬虫文件基本结构
2、配置start_urls-起始url,rules-需要爬取url的规则,注:scrapy框架会自动去除重复的url
3、在parse_xxxx(self, response)方法里面解析并返回数据给pipline
#xx_spider.py import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from qsbk_download.items import QsbkDownloadItem class QsbkDzSpiderSpider(CrawlSpider): name = 'qsbk_dz_spider' allowed_domains = ['qiushibaike.com'] #爬起数据起始页 start_urls = ['https://www.qiushibaike.com/text/page/1/'] #自动爬取url规则,callback指定处理该爬取该url规则的函数,follow是否在url规则返回数据里面跟踪满足条件的url rules = ( Rule(LinkExtractor(allow=r'.+text/page/\d+'), callback='parse_page', follow=True), #https://www.qiushibaike.com/article/124856819 Rule(LinkExtractor(allow=r'.+article/\d+'), callback='parse_detail', follow=False), ) def parse_page(self, response): # item = {} # #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get() # #item['name'] = response.xpath('//div[@id="name"]').get() # #item['description'] = response.xpath('//div[@id="description"]').get() # return item pass def parse_detail(self, response): """解析段子详情页""" #段子内容 dz_content = "".join(response.xpath("//div[@class='content']/text()").getall()).strip() print(dz_content) #段子搞笑毒 dz_funy = response.xpath("//i[@class='number']/text()").get().strip() print(dz_funy) #段子发布时间 dz_datetime = response.xpath("//span[@class='stats-time']/text()").get().strip() print(dz_datetime) #段子url地址 dz_url = response.url print(dz_url) #把数据传递给pipline yield QsbkDownloadItem(dz_content=dz_content, dz_funy=dz_funy, dz_datetime=dz_datetime, dz_url=dz_url)
4、pipline里面保存数据
#piplines.py from itemadapter import ItemAdapter from scrapy.exporters import JsonLinesItemExporter class QsbkDownloadPipeline: def __init__(self): self.fp = open("dz_joke.json", "wb") self.exp = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding="utf-8") def process_item(self, item, spider): self.exp.export_item(item) return item def close_spider(self, spider): self.fp.close()
三、Request对象与Response对象
Request对象:(from scrapy import Request)
作用:爬取一页数据发送一个请求时调用。这个类需要传递一些参数。
常用参数
url: Request对象发送请求的url
callback: 在下载器下载完后处理数据的回调函数
method: 请求的方法,默认是GET方法,也可以设置成其他的
headers: 请求头,对于一些固定的设置,放在settings.py指定即可;对于非固定的,可以在发送请求时指定
meta: 比较常用,用于在不同请求之间传递数据用
encoding: 编码。默认utf-8,使用默认的就可以了
dot_filter: 默认True;设置为False表示不由调度器过滤,在执行多次重复的请求的时候用得比较多
errback: 发生错误的时候执行的函数
Response对象:
作用:Response一般是有scrapy框架自动帮我们构建的,可以用来提取数据
常用属性和方法
meta: 从其他请求传递过来的meta属性,可以保持多个请求之间的数据连接
encoding:返回当前字符串编码和解码的格式
text: 将返回来的数据作为unicode字符串返回(解码后的字符串,有时候可能解码不对,需要使用body进行手动解码)
body: 将返回来的数据作为bytes字符串返回
url:返回请求的url地址
xpath(): xpath选择器
css(): css选择器
urljoin(part_url):把不完整part_url根据域名自动合成完整url,返回值完整url
四、发送POST请求
要发送POST请求,需要使用Request的子类FormRequest来实现。想要一开始就发送POST请求,需要在爬虫类中重写start_requests(self)方法,并且不再调用start_urls里面的url。
import scrapy
class TestPostSpiderSpider(scrapy.Spider):
name = 'test_post_spider'
allowed_domains = ['mail.qq.com']
#重写start_requsets后,start_urls将不会生效
start_urls = ['http://mail.qq.com/']
def start_requests(self):
url = "http://mail.qq.com/"
data = {"email": "2361261017@qq.com", "password":"1059855897jyd"}
request = scrapy.FormRequest(url, formdata=data, callback=self.parse_login)
#这个请求不会登录成功,只是做个演示
yield request
def parse(self, response):
pass
def parse_login(self, response):
#这里写登录成功后发送的请求
pass
识别验证码:
(1)分析请求,构造formdata的时候携带验证码相关参数
(2) 三方验证码识别平台:https://market.aliyun.com/,搜索识别验证码对图片进行base64编码与解码:使用内置模块base64
base64.b64encode(data):对图片二进制数据进行base64编码
base64.b64decode(data):对base64编码后的图片二进制数据进行解码
import base64 with open("123.jpg", "rb") as f: #对图片二进制数据进行base64编码 base64_img = base64.b64encode(f.read()) print(base64_img) with open("123副本.jpg", "wb") as f: #对base64编码后的图片二进制数据进行解码 b_img = base64.b64decode(base64_img) f.write(b_img)
五、下载文件和图片
Scrapy为下载item中包含的文件(比如爬取到某个产品时,同时也想保存响应的图片)提供了一个可重用的item piplines。
这些pipline有些共同的方法和结构(称为media pipeline)。一般使用Files Pipline 或者 Images Piplines
选择scrapy内置下载文件方法的好处:
- 避免重新下载最近已经下载过的数据
- 可以方便的指定文件存储路径
- 可以将下载的图片转换成通用的格式。比如png或jpg
- 可以方便生成缩略图
- 可以方便检测图片的宽和高,确保他们满足最小限制
- 异步下载效率非常高
下载文件的FilesPipeline使用步骤:
1、定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files。file_urls是用来存储需要下载的图片的url连接,需要给一个列表
2、当文件下载完成后,会把文件下载的相关信息存储到item的files属性中。比如下载路径,下载的url和文件的校验码等
3、在配置文件settings.py中配置FILES_STORE,这个配置是用来设置图片下载路径的
4、启动pipeline:在settings.py中配置ITEM_PIPLINES设置scrapy.pipelines.files.FilesPipeline:1
下载图片的ImagesPipline使用步骤:
1、定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images。image_urls是用来存储需要下载的图片的url连接,需要给一个列表
2、当文件下载完成后,会把文件下载相关信息存储到item的images属性中。比如下载路径,下载的url和图片的校验码等
3、在配置文件settings.py中配置IMAGES_STORE,这个配置是用来设置图片下载路径的
4、启动pipeline:在settings.py中配置ITEM_PIPLINES设置scrapy.pipelines.images.ImagesPipeline:1
重写ImagesPipline:
为了对文件进行分类,就需要重写这个类(自定义一个类继承自scrapy.pipelines.images.ImagesPipeline)
1、重写get_media_requests(self, item, info)方法:这个方法是发送请求之前调用,其作用就是发送下载请求
2、重写file_path(self, request, response=None,info=None)方法:这个方法是在图片将要被存储的时候调用,其作用是获取这个图片存储的路径
3、启动pipeline:在settings.py中配置ITEM_PIPLINES设置自己重写的pipeline
#xx_spider.py import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from qsbk_download.items import QsbkDownloadImageItem class QsbkImgSpiderSpider(CrawlSpider): name = 'qsbk_img_spider' allowed_domains = ['qiushibaike.com'] start_urls = ['https://www.qiushibaike.com/imgrank/page/1/'] rules = ( #https://www.qiushibaike.com/imgrank/page/2/ Rule(LinkExtractor(allow=r'.*/imgrank/page/\d+'), callback='parse_item', follow=True), #https: // www.qiushibaike.com / article / 124999370 Rule(LinkExtractor(allow=r'.*/article/\d+'), callback='parse_detail', follow=False), ) def parse_item(self, response): # item = {} #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get() #item['name'] = response.xpath('//div[@id="name"]').get() #item['description'] = response.xpath('//div[@id="description"]').get() # return item pass def parse_detail(self, response): content = response.xpath("//div[@class='image']/div[@class='content']/text()").get().strip() # print(content) img_url = response.urljoin(response.xpath("//div[@class='image']/div[@class='thumb']/img/@src").get().strip()) # print(img_url) item = QsbkDownloadImageItem(image_urls=[img_url, ], images=content) yield item
#pipelines.py from scrapy.exporters import JsonLinesItemExporter from scrapy.pipelines.images import ImagesPipeline import time . . . class QsbkDownloadImagePipeline(ImagesPipeline): """自定义下载图片piplines""" def file_path(self, request, response=None, info=None, *, item=None): download_time = "%s年%s月%s日" % tuple(time.strftime("%Y-%m-%d", time.localtime()).split("-")) img = request.url.split("/")[-1] img_name = img.split(".")[0] print(item) return '%s/%s.jpg' % (download_time, img_name)
#settings.py ITEM_PIPELINES = { # 'qsbk_download.pipelines.QsbkDownloadPipeline': 300, # 'scrapy.pipelines.images.ImagesPipeline': 200, 'qsbk_download.pipelines.QsbkDownloadImagePipeline':10, } IMAGES_STORE = ".//dz_img"
六、下载器中间件
下载器中间件是引擎和下载器之间通信的中间件。在这个中间件中我们可以设置代理、更换请求头等来达到反反爬虫的目的。要写下载器中间件,可以在下载器中实现两个方法:
1、process_request(self, request, spider):这个方法会在请求发送之前执行
process_request(self, request, spider)
作用:下载器发送请求前执行,一般可以在这里设置随机代理IP,随机请求头
参数:request --发送请求的request对象; spider --发送请求的spider对象
返回值:
如果返回None:Scrapy将继续处理该请求,执行其他中间件中相应方法,直到合适的下载器处理函数被调用
返回Response对象:Scrapy将不会调用任何其他的process_request()方法,将直接返回这个response对象。已经激活的中间件的process_response()方法则会在每个response返回时被调用
返回Request对象:不在使用之前的request对象去下载数据,而是根据现在返回的request对象返回数据
如果该方法中出现了异常,则对调用process_exception方法
2、process_response(self,request,response,spider):这个方法是数据下载到引擎之前执行
process_response(self,request,response,spider)
作用:这个方法是下载器下载的数据到引擎之前会执行的方法
参数:request --request对象;response --被处理的response对象;spider --spider对象
返回值:
返回Response对象:会将这个新的response对象传给其他中间件,最终传给爬虫
返回Request对象:下载器链被切断,返回的request会重新被下载器调度下载
如果抛出一个异常,那么调用request的errback方法,如果没有指定这个方法,那么会抛出一个异常
3、使用步骤:
(1)创建一个类,写在middlewares.py中:
(2)实现相关需要的中间件方法,如:
process_request(self, request, spider)
process_response(self,request,response,spider)
(3)在settings.py中打开DOWNLOADER_MIDDLEWARES并把写好的中间件类配置在里面
4、随机请求头中间件
爬虫频繁访问一个页面的时候,如果请求头保持一致。那么很容易被服务器发现,从而禁掉这个请求头。
注:重复访问一个网址
Scrapy有自动去重的功能,如果不想去重,把发送请求Requset对象的dont_filter设置为True。【scrapy.Request(url, dont_filter=True)】
#在middlewares.py里面写,并在setting.py里面注册中间件类后生效
class TestMiddleware:
"""自定义中间件"""
USER_AGENT = [
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
"Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)",
]
def process_request(self, request, spider):
user_agent = random.choice(self.USER_AGENT)
print("在my_process_reusets---设置请求头:", user_agent)
request.headers["User_Agent"] = user_agent
5、IP代理池中间件
#在middlewares.py里面写,并在setting.py里面注册中间件类后生效
class TestMiddleware:
"""自定义中间件"""
USER_AGENT = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
"Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)",
]
PROXIES = ["14.215.212.37:9168", "","27.208.139.89:8060"]
def process_request(self, request, spider):
#设置随机请求头
user_agent = random.choice(self.USER_AGENT)
request.headers["User_Agent"] = user_agent
print("在my_process_reusets---设置请求头:", user_agent)
#设置随机代理
proxy = random.choice(self.PROXIES)
request.meta['proxy'] = proxy
print("在my_process_reusets---设置代理:", proxy)
七、使用twisted异步存储到MySQL数据库中
需要安装pymysql模块
twisted是安装scrapy自带的
在pipelines.py中存储数据,创建一个pipline类存储数据
使用步骤:
1、twisted中导入adbapi
from twisted.enterprise import adbapi2、使用adbapi创建一个连接池
dbprames = {
'host':'127.0.0.1',
'port':3306,
'user':'root',
'password':'fy001',
'database':'test01',
'charset':'utf8',
'cursorclass':cursor.DictCursor,
}
dppool = adbapi.ConnectionPool('pymysql', **dbparames)
注:cursors.DictCursor是pymysql模块里面的游标对象,用于插入数据3、使用连接池dbpool对象的runInteraction(func)执行插入数据的函数
runInteraction()方法会返回一个defer对象,用于处理添加数据时候的错误的函数
defer.addErrback(func, *args)class QsbkDownloadToMysqlPipeline: """存储到mysql数据库的Pipeline""" def __init__(self): self.dbprames = {"host": "127.0.0.1", "port": 3306, "user": "root", "password": "123456", \ "database": "qsbk", "charset": "utf8", "cursorclass": pymysql.cursors.DictCursor} self._sql = "insert into qsbk_dz values(%s,%s,%s)" # url, content, funy self.dbpool = adbapi.ConnectionPool("pymysql", **self.dbprames) def process_item(self, item, spider): refer = self.dbpool.runInteraction(self.inset_item, item) refer.addErrback(self.inset_error, item, spider) def inset_item(self, cursor, item): cursor.execute(self._sql, (item["dz_url"], item["dz_content"], item["dz_funy"])) def inset_error(self, error, item, spider): print("出现错误".center(100, "-")) print(error)
八、 scrapy嵌入selenium + chromdriver
使用中间件,让chromdriver处理请求,返回chormdriver生成的页面
使用步骤:
1、创建一个中间件类,构造一个driver对象
self.driver = webdriver.Chorme(executable_path="chromdriver路径")
2、在process_request(self, request,spider)方法中利用dirver处理请求,并用driver获取到的页面构造一个响应并返回
self.driver.get(request.url)
time.sleep(1) #等待页面数据生成
source = self.driver.page_source
response = HtmlResponse(url=self.current_url, body=source, request=request)
return reponse
九、分布式爬虫
scrapy-redis组件,利用redis分布式功能集成到scrapy框架中
编写Scrapy-Redis分布式爬虫
将一个Scrapy项目变成一个Scrapy-redis项目只需修改以下三点:
1、将爬虫的类从scrapy.Spider修改成scrapy_redis.spiders.RedisSpider
或从scrapy.CrawlSpider变成scrapy_redis.spiders.RedisCrawlSpider
2、将爬虫的start_urls删掉。增加一个redis_key = "xxx"。 这个redis_key是为了以后在redis中控制爬虫启动的。爬虫的第一个url,就是在redis中通过这个发出去的
3、在配置文件中增加配置
#Scrapy-Redis相关配置
#确保request存储到redis中
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#确保所有爬虫共享相同的去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFileter"
#设置redis为item pipline
ITEM_PIPLINES = {"scrapy_redis.pipelines.RedisPipline":300}
#在redis中保持scrapy-redis用到的队列,不会清理redis中的队列,从而可以实现暂停恢复功能
SCHEDULER_PERSIST =True
#设置连接redis信息
REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
4、运行爬虫
在爬虫服务器上,进入爬虫文件所在路径,然后输入命令:scrapy runspider 爬虫名字在redis服务器上,推入一个开始的url链接:(注:redis_key和爬虫文件里面redis_key要一致)
redis-cli
lpush redis_key start_url