爬虫 分布式

11

- 手动请求的发送
    - yield scrapy.Request(url,callback)/FormRequest(url,callback,formdata)
- 深度爬取/全站数据的爬取
- 请求传参:
    - 使用场景:爬取的数据没有在同一张页面。深度爬取
    - yield scrapy.Request(url,callback,meta={})/FormRequest(url,callback,formdata,meta={})
        - item = response.meta['item']
- start_requests(self):
    - 作用:将start_urls列表中的列表元素进行get请求的发送
- 核心组件
- PyExcJs:模拟执行js程序
    - 安装好js环境- nodeJs的环境

- js混淆
- js加密
- robots
- UA伪装
- 代理
- Cookie
- 动态变化的请求参数
- 验证码
- 图片懒加载
- 页面动态加载的数据

 

下载中间件
    - 作用:批量拦截整个工程中发起的所有请求和响应
    - 为什么要拦截请求
        - UA伪装:
            - process_request:request.headers['User-Agent']= xxx
        - 代理ip的设定
            - process_exception:request.meta['proxy']= ’http://ip:port‘

    - 为什么要拦截响应
        - 篡改响应数据/篡改响应对象

    - 注意:中间件需要在配置文件中手动开启


网易新闻爬取
- 需求:网易新闻中国内,国际,军事,航空,无人机这五个板块下的新闻标题和内容
    创建一个四字段的库表(title,content,keys,type)
- 分析:
    1.每一个板块下对应的新闻标题数据都是动态加载出来的
    2.新闻详情页的数据不是动态加载的


 - 在scrapy中使用selenium
    - 在爬虫文件的构造方法中实例化一个浏览器对象
    - 在爬虫文件中重写一个closed(self,spider)方法,关闭浏览器对象
    - 在下载中间件的process_response中获取浏览器对象,然后执行浏览器自动化的相关操作

CrawlSpider的全站数据爬取
    - CrawlSpider就是另一种形式的爬虫类。CrawlSpider就是Spider的一个子类
    - 创建一个基于CrawlSpider的爬虫文件:
        - scrapy genspider -t crawl spiderName www.xxx.com


分布式
    - 概念:组建一个分布式的机群,让分布式机群对同一组数据进行分布爬取.
    - 作用:提升数据爬取的效率
    - 如何实现分布式?
        - scrapy+redis实现的分布式
            - scrapy结合着scrapy-redis组建实现的分布式

    - 原生的scrapy是无法实现分布式
        - 调度器无法被分布式机群共享
        - 管道无法被分布式机群共享

    - scrapy-redis的作用是什么?
        - 给原生的scrapy提供了可以被共享的调度器和管道
    - 为什么这个组建叫做scrapy-redis?
        - 分布爬取的数据必须存储到redis中

    - 编码流程:
        - pip install scrapy-redis
        - 创建爬虫文件(CrawlSpider/Spider)
        - 修改爬虫文件:
            - 导入scrapy-redis模块封装好的类
                - from scrapy_redis.spiders import RedisCrawlSpider
            - 将爬虫类的父类指定成RedisCrawlSpider
            - 将allowed_domains和start_urls删除
            - 添加一个新属性:redis_key = 'xxx'#可以被共享的调度器队列的名称
        - 进行settings文件的配置:
            - 指定管道:
                ITEM_PIPELINES = {
                    'scrapy_redis.pipelines.RedisPipeline': 400
                }
            - 指定调度器
                DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
                SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                SCHEDULER_PERSIST = True

            - 指定数据库
                REDIS_HOST = 'redis服务的ip地址'
                REDIS_PORT = 6379

        - 配置redis的配置文件redis.windows.conf:
            - 56行:#bind 127.0.0.1
            - 关闭保护模式:protected-mode no

        - 启动redis服务:
            - redis-server ./redis.windows.conf
            - redis-cli
        - 执行程序:
            进入到爬虫文件对应的目录中:scrapy runspider xxx.py
        - 向调度器队列中放入一个起始的url:
            - 调度器的队列名称就是redis_key值
                - 在redis-cli:lpush 队列名称  www.xxx.com

分布式

1pip install scrapy-redis

2创建爬虫文件

3修改爬虫文件

        - 导入scrapy-redis模块封装好的类
                 - from scrapy_redis.spiders import RedisCrawlSpider(仅为举例)
            - 将爬虫类的父类指定成RedisCrawlSpider
            - 将allowed_domains和start_urls删除
            - 添加一个新属性:redis_key = 'xxx'#可以被共享的调度器队列的名称

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

from scrapy_redis.spiders import RedisCrawlSpider
from fbsPro.items import FbsproItem
class FbsSpider(RedisCrawlSpider):
    name = 'fbs'

# allowed_domains = ['www.xxx.com'] # start_urls = ['http://www.xxx.com/']
redis_key
= 'sunQueue' #可以被共享的调度器队列的名称 rules = ( Rule(LinkExtractor(allow=r'type=4&page=\d+'), callback='parse_item', follow=True), ) def parse_item(self, response): tr_list = response.xpath('//*[@id="morelist"]/div/table[2]//tr/td/table//tr') for tr in tr_list: title = tr.xpath('./td[2]/a[2]/text()').extract_first() item = FbsproItem() item['title'] = title yield item

setting 配置

        - 指定管道:
                ITEM_PIPELINES = {
                    'scrapy_redis.pipelines.RedisPipeline': 400
                }
            - 指定调度器
                DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
                SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                SCHEDULER_PERSIST = True

            - 指定数据库
                REDIS_HOST = 'redis服务的ip地址'

 

BOT_NAME = 'fbsPro'

SPIDER_MODULES = ['fbsPro.spiders']
NEWSPIDER_MODULE = 'fbsPro.spiders'

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'fbsPro (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False


# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 2

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False

# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
#}

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'fbsPro.middlewares.FbsproSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'fbsPro.middlewares.FbsproDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
#ITEM_PIPELINES = {
#    'fbsPro.pipelines.FbsproPipeline': 300,
#}

# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'


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_HOST = '192.168.16.53'
REDIS_PORT = 6379
    - 配置redis的配置文件redis.windows.conf:
            - 56行:#bind 127.0.0.1
            - 关闭保护模式:protected-mode no

   - 启动redis服务:
            - redis-server ./redis.windows.conf
            - redis-cli
   - 执行程序:
            进入到爬虫文件对应的目录中:scrapy runspider xxx.py

 

- 向调度器队列中放入一个起始的url:
            - 调度器的队列名称就是redis_key值
                - 在redis-cli:lpush 队列名称  www.xxx.com

 

item .py 文件

import scrapy


class FbsproItem(scrapy.Item):
    # define the fields for your item here like:
    title = scrapy.Field()
    # pass

 

posted @ 2019-08-10 18:01  我的IT007  阅读(146)  评论(0编辑  收藏  举报