day05-scrapy框架基础

  • 工作流程图

img

  • scrapy Engine(引擎):负责Spider、itemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等

  • Scheduler(调度器):它负责接收引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引 擎需要时,交还给引擎。

  • Downlaoder(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将器获取到的Response交还给Scrapy Engine(引擎),由引擎交给Spider来处理

  • Spider(爬虫):他负责处理所有Response,从中分析提取数据,获取item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)

  • item Pipelien(管道):它负责处理Spider中获取的item,并进行后期处理(详细分析、过滤、存储等)的地方。

  • Downloader Middlewares(下载中间件):可以当做是一个可以自定义扩展下载功能的组件。

  • Spider Middlewares(Spider中间件):你可以理解为是一个可以自定义扩展和操作引擎和Spider中间通信的功能组件。(比如进入Spider的Response;和从Spider出去的Requests)

img

  • 创建项目:scrapy startproject 'name'

  • 进入项目:cd 'name'

  • 创建爬虫:scrapy genspider 'name' xxx.com(域名)

  • 数据存储:scrapy crawl xxx -o xxx.json (局限性很大)

  • 运行爬虫:scrapy crawl xxx

非命令行运行:

  • 在项目跟目录创建一个py文件
from scrapy.cmdline import execute

execute(("scrapy crawl sun").split())

# 直接右键运行

1.编码流程

#  1.使用scrapy创建项目:
#       scrapy startproject proname

#  2.创建spider
#       2.1 cd proname
#       2.2 scrapy genspider spidername xxx.com

#  3.在spider中修改信息(allow_domains和start_urls)
#       allow_domains:允许的域,不在域的范围之内的url讲不会发送请求
#       start_urls:起始的url,第一个请求的url

#  4.编写items:
#        需要爬取哪些字段,在这里定义好

#  5.编写spider代码
#     - 默认的parse方法是对于start_urls请求的响应
#     - 构造item,然后yield item,会把item传递给管道

#  6.启动scrapy
#      scrapy crawl spidername --nolog (保证在根目录)(--nolog可以不显示调试信息,只显示我们自己定义的print)
#
#  7. 保存数据
#      在spider里面yield的item会传递到pipeline中来
#      需要在pipeline管道中定义数据的保存逻辑
#      def open_spider(self, spider): # 爬虫开启的时候执行一次,可以用来打开文件
#      def close_spider(self, spider):#  爬虫关闭的时候执行一次,用来关闭文件
#      process_item : 用来处理数据的保存
#      注意:一定要在settings中开启item_pipeline管道,这样管道才能生效


- settings.py:
  - 不遵从robots协议
  - 进行UA伪装
  - 进行日志等级设定:LOG_LEVEL = 'ERROR'

- 持久化存储:
  - 基于终端指令:
    - 特性:只可以将parse方法的返回值存储到本地的磁盘文件中
    - 指令:scrapy crawl spiderName -o filePath

  - 基于管道:实现流程
    1.数据解析
    2.在item类中定义相关的属性
    3.将解析的数据存储或者封装到一个item类型的对象(items文件中对应类的对象)
    4.向管道提交item
    5.在管道文件的process_item方法中接收item进行持久化存储
    6.在配置文件中开启管道

  - 将同一份数据持久化到不同的平台中?
    - 分析:
      - 1.管道文件中的一个管道类负责数据的一种形式的持久化存储
      - 2.爬虫文件向管道提交的item只会提交给优先级最高的那一个管道类
      - 3.在管道类的process_item中的return item表示的是将当前管道接收的item返回/提交给
        下一个即将被执行的管道类

2.中间件

  • Spider middlewares
    • 几乎用不到!
  • Download middlewares
    • 发送请求之前可以修改请求头信息:在settings配置中打开中间件

      • from fake_useragent import FakeUserAgent
        # 自定义一个类(类名无所谓) 定义 process_request()方法,返回None即可
        # 安装一个fake-useragent第三方库随机获取请求头
        class UserAgentDownloaderMiddleware:
            def process_request(self, request, spider):
                request.headers['User-Agent'] = FakeUserAgent().random
                return None
            
            # 返回响应之前要什么事可以定义这个方法
            def process_response(self, request, response, spider):
                print(request.headers)
                return response
        
        
    • 使用代理

      • # 用法跟上面一样
        class ProxyDownloaderMiddleware:
            def process_request(self, request, spider):
                request.meta['proxy'] = "代理ip"
                #  添加代理
                return None
        
  • 3.发送post请求

    • 有两种方法:

      • 方式一:模拟登录

        • class SunSpider(scrapy.Spider):
              name = 'sun'
              # allowed_domains = ['xxx.com']
              # start_urls = ['http://www.renren.com/PLogin.do']
          
              # 重写start_request方法
              def start_requests(self):
                  url = 'http://www.renren.com/PLogin.do'
                  data = {
                      'email': '17620521408',
                      'password': '168768..'
                  }
                  yield scrapy.FormRequest(url, formdata=data, callback=self.parse)
          
              def parse(self, response):
                  print(response.body.decode())
          
          
      • 方式二:使用cookie

        • class SunSpider(scrapy.Spider):
              name = 'sun'
              # allowed_domains = ['xxx.com']
              # start_urls = ['http://www.renren.com/PLogin.do']
          
              # 重写start_request方法    
              def start_requests(self):
                  url = 'http://photo.renren.com/photo/974591038/albumlist/v7?offset=0&limit=40#'
                  cookies = '把登录后的cookie放进来处理一下'
                  
                  cookies = {i.split('=')[0]: i.split('=')[1] for i in cookies.split('; ')}
                  
                  yield scrapy.Request(url, callback=self.parse, cookies=cookies, dont_filter=True)
          
              def parse(self, response):
                  yield scrapy.Request('http://photo.renren.com/photo/974591038/albumlist/v7?offset=0&limit=40#', callback=self.parse_detail)
          
              def parse_detail(self,response):
                  print(response.body.decode())
          
        • 总结:

          scrapy中模拟登录:两种方法
          
          找到post登录接口,构造表单数据,构造POST请求对象,传递参数
          
          使用cookie,访问登录以后的页面,把cookie作为参数传递到Request对象中
          
          重写start_requests方法
          
          scrapy中默认支持cookie持久化,只需要传递一次cookie或者模拟登录一次(post),后续所有请求默认都会带入cookie
          
          dont_filter:不过滤请求,默认为False,就是会过滤相同的请求
          
posted @ 2020-07-29 00:36  老宝  阅读(80)  评论(0)    收藏  举报