分佈式爬蟲與增量式爬蟲

一.提高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,進程線程協成,協成怎麼實現,爬蟲,運維

算法 總體回顧總結 博客整理

項目:

基於...實現的... :十分鐘

基於...實現的...:十分鐘

基於...實現的...:十分鐘

基於...實現的...:十分鐘

項目背:

看頁面想

打斷:反問

你考我這個

加微信

相關文章
相關標籤/搜索