分布式爬虫与增量式爬虫

一.提高scrapy爬取数据的效率

  • 增长并发redis

    默认scrapy开启时并发线程为32个,能够适当的增长算法

    CONCURRENT_REQUESTS =32微信

  • 下降日志级别cookie

    在运行scrapy时,会有大量的日志信息输出,为了减小CPU的使用路,能够设置log的输出信息为error便可并发

    LOG_LEVEL="ERROR"运维

  • 禁止cookiedom

    若是不是真的须要cookie,则在scrapy的使用时能够禁止cookie,从而减小CPU的使用率,提高爬取效率scrapy

    COOKIES_ENABLED=False分布式

  • 禁止重试ide

    对失败的HTTP从新请求,会减慢爬取速度,所以能够禁止重试

    RETRY_ENABLED=False

  • 减小下载超时

若是对一个很是慢的连接进行爬取,减小下载超时可让卡住的连接快速被放弃,从而提高小效率

DOWNLOAD_ENABLED=10

 

二.Crawlspider

建立基于Crawlspider 的爬虫文件

scrapy genspider -t crawl chouti www.xxx.com

做用1:可以在页面中查找指定url,并去重,解析

实例一:糗百爬取

在爬虫文件中

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from choutipro.items import ChoutiproItem
item=ChoutiproItem()
#注:继承的父类再也不试Spider类,是CrawlSpider
class ChoutiSpider(CrawlSpider):
   name = 'qiubai'
   # allowed_domains = ['www.xxx.com']
   start_urls = ['https://www.qiushibaike.com/text/']
   #1.连接提取器,allow表示的是连接提取器提取连接的规则
   link=LinkExtractor(allow=r'/text/page/\d+/')
   link1=LinkExtractor(allow=r'/text/$')
   rules = (
       #2.规则解析器:将连接提取器所对应的页面数据进行指定形式的解析
       Rule(link, callback='parse_item', follow=False),
       Rule(link1, callback='parse_item', follow=False),
  )

   def parse_item(self, response):
       item = {}
       div_list=response.xpath('//*[@id="content-left"]/div')
       for div in div_list:
           content=div.xpath('./a/div/span/text()').extract_first()
           item["content"]=content
           yield item
       return item

在items.py中

import scrapy
class ChoutiproItem(scrapy.Item):
   # define the fields for your item here like:
   content = scrapy.Field()
   pass

在管道文件中

class ChoutiproPipeline(object):
   f=None
   def open_spider(self,spider):
       print("开始爬虫!")
       self.f= open('./qiubai.txt','w',encoding='utf-8')
   def process_item(self, item, spider):
       self.f.write(item['content']+"\n")
       return item
   def close_spider(self,spider):
       print("结束爬虫!")
       self.f.close()

 

案例二:全部连接

做用2:可以在页面中递归查找指定url,并去重,解析

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from choutipro.items import ChoutiproItem
item=ChoutiproItem()
#注:继承的父类再也不试Spider类,是CrawlSpider
class ChoutiSpider(CrawlSpider):
   name = 'qiubai'
   # allowed_domains = ['www.xxx.com']
   start_urls = ['https://www.qiushibaike.com/text/']
   #1.连接提取器,allow表示的是连接提取器提取连接的规则
   link=LinkExtractor(allow=r'/text/page/\d+/')
   link1=LinkExtractor(allow=r'/text/$')
   rules = (
       #2.规则解析器:将连接提取器所对应的页面数据进行指定形式的解析
       Rule(link, callback='parse_item', follow=True),
       Rule(link1, callback='parse_item', follow=True),
  )
   #follow=True表明将连接提取器继续做用到连接提取器提取到的连接所对应的页面

   def parse_item(self, response):
       item = {}
       div_list=response.xpath('//*[@id="content-left"]/div')
       for div in div_list:
           content=div.xpath('./a/div/span/text()').extract_first()
           item["content"]=content
           yield item
       return item

 

三.分布式爬虫(多台机器)

1.为何原生scrapy不能实现分布式

  • 调度器不能被共享

  • 管道没法共享

2.scrapy-redis组件的做用

提供了能够被共享的调度器和管道

3.分布式爬虫流程

1.环境安装:pip3 install scrapy-redis
2.建立工程:
scrapy startproject redischoutipro
cd redischoutipro
3.建立爬虫文件,基于RedisCrawlSpider
scrapy genspider -t crawl chouti www.xxx.com
4.对爬虫文件中的相关属性进行修改
(1)导包:
from scrapy_redis.spiders import RedisCrawlSpider
(2)将当前爬虫文件的父类改为RedisCrawlSpider
(3)注释掉allowed_domains和start_urls,由于不须要其实url,由于分布式爬虫的多台机器中的代码时同样的,在一台机器上扔出一个起始url,哪台机器抢到哪台机器就对起始页面发送请求
(4)将起始url替换成url_key,表示调度器队列的名称:
redis_key = 'chouti'
5.编写爬虫文件,items文件
6.在配置文件中进行配置
(1)使用组件中封装好的能够被共享的管道类:
ITEM_PIPELINES={
  'scrapy_redis.piplines.RedisPiplines':400
}
(2)配置调度器,使用组建中封装好的能够被共享的调度器
DUPEFILTER_CLASS='scrapy_redis.dupefilter.RFPDupeFilter'
SCHEDULER='scrapy_redis.scheduler.Scheduler'
SCHEDULER_PERSIST= True
指定存储数据的redis
REDIS_HOST='127.0.0.1'
REDIS_PORT=6379
修改ua,robots协议
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'
ROBOTSTXT_OBEY = False
7.启动redis,redis也须要配置
在配置文件中取消保护模式
protected-mode no
bing绑定取消
#bing 127.0.0.1
从新启动启动redis,让配置文件生效
redis-cli
6.执行分布式程序(必定要在该目录下)
scrapy runspider chouti.py
7.向调度器队列中扔入起始url
在redis-cli中执行:
lpush chouti https://dig.chouti.com/all/hot/recent/1
8.查看redis中是否爬到了数据
keys *
lrange chouti:items0 -1

爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from redischoutipro.items import RedischoutiproItem
#1.导包
from scrapy_redis.spiders import RedisCrawlSpider

item=RedischoutiproItem()

class ChoutiSpider(RedisCrawlSpider):
   name = 'chouti'
   # allowed_domains = ['www.xxx.com']
   # start_urls = ['http://www.xxx.com/']
   redis_key = 'chouti' #表示调度器队列的名称
   rules = (
       Rule(LinkExtractor(allow=r'/all/hot/recent/\d+'), callback='parse_item', follow=True),
  )

   def parse_item(self, response):
       div_list=response.xpath('//div[@class="item"]')
       for div in div_list:
           content=div.xpath('./div[4]/div[1]/a/text()').extract_first()
           name=div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first()
           print(name)
           print(1111111111111)
           print(content)
           item["name"]=name
           item["content"]=content
           yield item #这样提交到的是原生scrapy的管道当中
       #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

items.py

import scrapy
class RedischoutiproItem(scrapy.Item):
   # define the fields for your item here like:
   name = scrapy.Field()
   content = scrapy.Field()
   pass

配置文件

#管道类
ITEM_PIPELINES={
   'scrapy_redis.pipelines.RedisPipeline':400
}
#调度器的配置
#去重容器的配置
DUPEFILTER_CLASS='scrapy_redis.dupefilter.RFPDupeFilter'
#组件本身的调度器
SCHEDULER='scrapy_redis.scheduler.Scheduler'
#调度器的配置是否持久化(爬虫结束是要不要清除redis请求队列和去重指纹的set)
SCHEDULER_PERSIST= True
#redis配置
REDIS_HOST='127.0.0.1'
REDIS_PORT=6379

 

四.增量式爬虫(只爬取最新的数据)

概念:经过爬虫程序检测网站数据的更新的状况,以即可以爬取到更新出的新数据

方式一:对url去重

 

对数据取哈希值,用哈希值判断是否重复(本身制定了一种形式的数据指纹)

 

注:redis2.10.6的版本之前才能够存字典

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

车牌多少,冒泡,快排,单例模式,http,进程线程协成,协成怎么实现,爬虫,运维

算法 总体回顾总结 博客整理

项目:

基于...实现的... :十分钟

基于...实现的...:十分钟

基于...实现的...:十分钟

基于...实现的...:十分钟

项目背:

看页面想

打断:反问

你考我这个

加微信

相关文章
相关标签/搜索