美文网首页
2020-07-19--scrapy框架1

2020-07-19--scrapy框架1

作者: program_white | 来源:发表于2020-07-19 23:38 被阅读0次

概览

在具体的学习scrapy之前,我们先对scrapy的架构做一个简单的了解,之后所有的内容都是基于此架构实现的,在初学阶段只需要简单的了解即可,之后的学习中,你会对此架构有更深的理解。 下面是scrapy官网给出的最新的架构图示。

基本组件

  • 引擎(Engine) 引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。
    详细内容查看下面的数据流(Data Flow)部分。

  • 调度器(Scheduler) 调度器从引擎接受request并将他们入队,以便之后引擎请求他们时提供给引擎。

  • 下载器(Downloader) 下载器负责获取页面数据并提供给引擎,而后提供给spider。 并去除处理完的请求。

  • 爬虫(Spiders) Spider是Scrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些)网站。

  • 管道(Item Pipeline) Item Pipeline负责处理被spider提取出来的item。典型的处理有清理、验证及持久化(例如存取到数据库中)。

  • 下载器中间件(Downloader middlewares) 下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的response。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。

  • Spider中间件(Spider middlewares) Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。

数据流向

Scrapy的数据流由执行引擎(Engine)控制,其基本过程如下:

引擎从Spider中获取到初始Requests。 引擎将该Requests放入调度器,并请求下一个要爬取的Requests。 调度器返回下一个要爬取的Requests给引擎 引擎将Requests通过下载器中间件转发给下载器(Downloader)。 一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎。 引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。 Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。 引擎将(Spider返回的)爬取到的Item交给ItemPipeline处理,将(Spider返回的)Request交给调度器,并请求下一个Requests(如果存在的话)。 (从第一步)重复直到调度器中没有更多地Request。

安装

pip install scrapy 

创建项目

在自己的项目目录下创建项目:

scrapy startproject cnblog

命令来在当前目录下创建一个新的项目。 下面我们创建一个爬取博客园('https://www.cnblogs.com/')文章信息的项目

cmd:

然后使用pycharm打开创建的项目文件:

打开后的项目目录:

下面简单的讲解一下各目录/文件的作用:

  • spiders/ 在这个文件夹下面,编写你自定义的spider。
  • items.py 定义你所要抓取的字段
  • middlewares.py 中间件,主要是对功能的拓展,你可以添加一些自定义的功能,比如添加随机user-agent, 添加proxy。
  • pipelines.py 管道文件,当spider抓取到内容(item)以后,会被送到这里,这些信息(item)在这里会被清洗,去重,保存到文件或者数据库。
  • settings.py 设置文件,用来设置爬虫的默认信息,相关功能开启与否,比如是否遵循robots协议,设置默认的headers,设置文件的路径,中间件的执行顺序等等。
  • scrapy.cfg 项目的配置文件,带有这个文件的那个目录作为scrapy项目的根目录

项目配置

在settings.py中配置以下内容:

#爬虫项目名
BOT_NAME = 'cnblog'

#爬虫模块的位置
SPIDER_MODULES = ['cnblog.spiders']
NEWSPIDER_MODULE = 'cnblog.spiders'
# 不遵循robots协议
ROBOTSTXT_OBEY = False
# 爬取url之间的时间间隔
DOWNLOAD_DELAY = 1
# 是否支持cookie
COOKIES_ENABLED = True
#默认请求头
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'en',
  # user-agent是新添加的
  'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}

编写爬虫

在terminal中创建爬虫文件:

scrapy genspider blog cnblogs.com

该文件在spiders目录下。
在该py文件下自动生成的代码:

import scrapy


class BlogSpider(scrapy.Spider):
    #自定义爬虫名
    name = 'blog'
    #限定网站域
    allowed_domains = ['cnblogs.com']
    #起始url集合
    start_urls = ['http://cnblogs.com/']

    #爬取方法
    def parse(self, response):
          pass

分析:
导入scrapy模块 定义一个spider类,继承自scrapy.Spider父类。 下面是三个重要的内容:

  • name: 用于区别Spider。 该名字必须是唯一的,不可以为不同的Spider设定相同的名字。这一点很重要。

  • start_urls: 包含了Spider在启动时进行爬取的url列表。第一个被获取到的页面将是其中之一。即这是爬虫链接的起点,爬虫项目启动,便开始从这个链接爬取,后续的URL则从初始的URL获取到的数据中提取。

  • parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。 修改settings.py文件 将settings.py文件里面的下列内容修改如下,其余的内容不动。

运行我们的爬虫项目 至此,项目必要的信息已经全部完成了,下面就是运行我们的爬虫项目 进入带有scrapy.cfg文件的那个目录,前面已经说过,这是项目的根目录,执行下面的命令:

scrapy crawl blog

blog是spiders/blog.py文件里面我们定义的那个具有唯一性的name 你会发现打印出了博客园首页的文章标题列表和文章的url信息,如下所示:
在blog.py中的parse()中编写爬虫:

    #爬取方法
    def parse(self, response:HtmlResponse):
        # print(type(response))      HtmlResponse对象
        # print(response)
        # print(f'内容:{response.text}')       #打印response文本

        # xpath:提供基于xpath路径方式解析    extract():类型转换,返回list类型
        title = response.xpath('//a[@class="titlelnk"]/text()').extract()
        title_url = response.xpath('//a[@class="titlelnk"]/@href').extract()
        print(f'类型:{type(title)},内容:{title}')
        print(f'类型:{type(title_url)},内容:{title_url}')

        print('*'*50)

        # css:提供基于css选择器解析
        title = response.css('a.titlelnk').extract()
        print(f'类型:{type(title)},内容:{title}')

解析方式:

  • xpath:提供基于xpath路径方式解析
    response.xpath('xpath语法').extract()
  • css:提供基于css选择器解析
    response.css('css选择器').extract(),css没有会直接获取信息的方法,要进一步解析才能获取。
  • response.text:打印响应的代码
  • extract():类型转换
    可将<class 'scrapy.selector.unified.SelectorList'><class 'list'>类型

结果:

数据存储

我们简单的实现了一个博客首页信息的爬取,并在控制台输出,但是,爬下来的信息自然是需要保存下来的。这一节主要是实现信息的存储,我们以将信息保存到文件为例,学习数据的存储,依然是以博客首页信息为例。

items.py:

import scrapy

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

爬虫文件blog.py:


import scrapy
from scrapy.http import HtmlResponse

from cnblog.items import CnblogItem
class BlogSpider(scrapy.Spider):
    #自定义爬虫名
    name = 'blog'
    #限定网站域
    allowed_domains = ['cnblogs.com']
    #起始url集合
    start_urls = ['http://www.cnblogs.com/']

    def parse(self, response):
        # 获取并解析数据,类型为list
        title = response.xpath('//a[@class="titlelnk"]/text()').extract()
        title_url = response.xpath('//a[@class="titlelnk"]/@href').extract()

        #依次封装数据
        for i in range(len(title)):
            #获取item对象
            it = CnblogItem()
            it['title'] = title[i]
            it['href'] = title_url[i]
            # print(it)
            # 将item对象传给管道pipelines
            yield it

在最后每当yield一次。管道就接受一次item数据。

管道pipelines.py:

class CnblogPipeline:
    
    def __init__(self):
        #创建文件
        self.wf = open('cnblog.txt','w',encoding='utf-8')

    def process_item(self, item, spider):
        # 获取item对象的数据
        s = f'标题:{item["title"]},href:{item["href"]}'
        #写入文件
        self.wf.write(s+"\n")
        self.wf.flush()
        #返回给引擎
        return item

这时管道并没有允许使用。

settings.py:

把注释去掉即可。

# 管道允许使用
ITEM_PIPELINES = {
   'cnblog.pipelines.CnblogPipeline': 300,
}

运行

在terminal中输入scrapy crawl blog

在项目目录下生成cnblog.txt:

相关文章

  • 2020-07-19--scrapy框架1

    概览 在具体的学习scrapy之前,我们先对scrapy的架构做一个简单的了解,之后所有的内容都是基于此架构实现的...

  • 2020-07-19--scrapy框架2

    scrapy调试 通常,运行scrapy爬虫的方式是在命令行输入scrapy crawl ,调试的常用方式是在命令...

  • 框架1

    女子,穿越架空,女扮男装,所用化名千百,行走江湖,大风大浪,街头巷尾,庙堂田埂,遇人形色,用情滑真。可惜本人文笔有...

  • Struts2(一)Struts2介绍及基本使用

    1.什么是框架 什么是框架,框架从何而来,为什么使用框架? 1).框架(framework)——半成品: 1.是一...

  • 20170602基础知识-语法基础、运算符

    1、import引入框架, Foundation框架是基础框架 macOS框架:Foundation、AppKit...

  • iOS-基本技术总结

    1、基本框架:Foundation框架、UIKit框架 2、高级框架:Core Data 、Core Graphi...

  • CoreText

    目录 1.CoreText框架概述 一、CoreText框架概述 1.CoreText框架图 2.Coretext...

  • 集合框架(1)

    01_集合框架(对象数组的概述和使用) A:案例演示需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历...

  • 1 集合框架

    java集合框架是一组封装好的Api,提供了大量的常用数据结构。最常见的如: 列表 map下面的小节中我们将介绍这...

  • 1 Latex 框架

    1.1 框架 1.2 标题 section 1.2.1 一级标题 1.2.2 二级标题 1.2.3 标题label...

网友评论

      本文标题:2020-07-19--scrapy框架1

      本文链接:https://www.haomeiwen.com/subject/kjmlkktx.html