虫虫

Scrapy框架之新建Scrapy项目详解

2019-02-22  本文已影响42人  不存在的一角
Scrapy架构王图

前言

从这篇开始,带大家通过 Scrapy 框架来写爬虫,相比之前写的爬虫脚本,用上 Scrapy 才更像一个爬虫项目

Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中

其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取 API 所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫

Scrapy 使用了 Twisted'twɪstɪd异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求

简单来说,Scrapy 就是一个方便爬虫搭建的框架,那么下面来看看我们的第一个 Scrapy 项目(其实之前就有一篇爬取堆糖的文章已经用过了,这里完整的来一遍)

今天主要讲解如何建一个 Scrapy 项目,以及** Scrapy 的基本结构和配置**

正文

首先,安装 Scrapy 可以在 Pycharm 中安装,也可以手动下载或通过命令行安装,这里就举个直接在 Pycharm 中是如何安装的

首先在 settings 中点击 Project interpreter ,右侧就是你当前使用的 Python 解释器已经安装的包,这里我已经装过了,还提示可以升级到 Scrapy 1.6.0

然后我们点击最右侧的绿色加号,在上方搜索 Scrapy 可以看到下方就出现了 scrapy ,右侧是其最新的版本,点击底部 Install Package 就可以安装,稍等几分钟就能装好了

接着来看看如何创建一个 Scrapy 项目,如下图所示,打开 cmd 命令行,什么?不会打开...

按 “Win + r” 键运行,输入 cmd 回车即可

接着进入自己经常放代码的文件夹下,在这里输入

scrapy startproject myscrapy

然后回车,myscrapy 是你自己定的项目名,之所以我这里是

python3 -m scrapy startproject myscrapy

是因为一开始我同时装了 Python2 和 Python3,所以执行命令时要区别,所以没有同时装两个版本的各位,可以不用跟我一样加上 python3 -m

到这里 Scrapy 项目就创建好了,但是我们还需要一个主要放爬虫代码的.py文件,而在我们创建完一个 Scrapy 之后也提示我们,可以进入这个项目,创建一个爬虫文件

cd myscrapy
scrapy genspider first "bilibili.com"

first 是爬虫名,“bilibili.com” 是为了方便自定义的爬取网站的域名

这样一来完整的 Scrapy 项目就创建完了,下面是完整的项目结构

这里

还有一点是,Scrapy 的命令可不止 startprojectgenspider,更多的可以直接在命令行中输入

scrapy

回车后就可以看见,而需要注意的是,没有进入项目文件下,与进入项目文件下可执行的 Scrapy 命令有点不同

没有进入项目文件夹 进入项目文件夹下

具体作用大家可以问问度娘~我就不再多说了(谁说我不知道了,这些小知识得自己搜过印象才深嘛)

项目结构以及如何创建 Scrapy 项目就先到这儿,下面我们来看看 Scrapy 到底有哪些五脏六腑

first.py

首先,我们的 first.py 文件,之后我们要写的爬虫主体代码就在此编写,可以看到生成的文件中,有一个 FirstSpider 类,继承着 scrapy.Spider

name 是爬虫名,之后运行爬虫的时候,就要用到这个 name
allowed_domains 包含了spider允许爬取的域名(domain)的列表
start_urls 初始URL元祖/列表
parse 方法,当请求url返回网页没有指定回调函数时,默认的Request对象回调函数。用来处理网页返回的response,以及生成Item或者Request对象

# -*- coding: utf-8 -*-
import scrapy


class FirstSpider(scrapy.Spider):
    name = 'first'
    allowed_domains = ['bilibili.com']
    start_urls = ['http://bilibili.com/']

    def parse(self, response):
        pass

items.py

Item 中定义结构化数据字段,用来保存爬取到的数据

可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field的类属性来定义一个Item

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class MyscrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()

    name = scrapy.Field()

middlewares.py

中间件文件中定义了两个中间件类 MyscrapySpiderMiddlewareMyscrapyDownloaderMiddleware

下载器中间件是介于 Scrapy 的request/response处理的钩子框架。 是用于全局修改Scrapy request和response的一个轻量、底层的系统

要使用下载器中间件,就需要激活,要激活下载器中间件组件,将其加入到 DOWNLOADER_MIDDLEWARES设置中。 该设置是一个字典(dict),键为中间件类的路径,值为其中间件的顺序(order),需在 settings,py 中配置

当然也可以自己编写中间件

将其注释解掉即可

#SPIDER_MIDDLEWARES = {
#    'myscrapy.middlewares.MyscrapySpiderMiddleware': 543,
#}

#DOWNLOADER_MIDDLEWARES = {
#    'myscrapy.middlewares.MyscrapyDownloaderMiddleware': 543,
#}
# -*- coding: utf-8 -*-

# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html

from scrapy import signals


class MyscrapySpiderMiddleware(object):
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # Called for each response that goes through the spider
        # middleware and into the spider.

        # Should return None or raise an exception.
        return None

    def process_spider_output(self, response, result, spider):
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, dict or Item objects.
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        # Called when a spider or process_spider_input() method
        # (from other spider middleware) raises an exception.

        # Should return either None or an iterable of Response, dict
        # or Item objects.
        pass

    def process_start_requests(self, start_requests, spider):
        # Called with the start requests of the spider, and works
        # similarly to the process_spider_output() method, except
        # that it doesn’t have a response associated.

        # Must return only requests (not items).
        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)


class MyscrapyDownloaderMiddleware(object):
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request
        # - or return a Response object
        # - or return a Request object
        # - or raise IgnoreRequest: process_exception() methods of
        #   installed downloader middleware will be called
        return None

    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object
        # - return a Request object
        # - or raise IgnoreRequest
        return response

    def process_exception(self, request, exception, spider):
        # Called when a download handler or a process_request()
        # (from other downloader middleware) raises an exception.

        # Must either:
        # - return None: continue processing this exception
        # - return a Response object: stops process_exception() chain
        # - return a Request object: stops process_exception() chain
        pass

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

pipelines.py

当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。

每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。

以下是item pipeline的一些典型应用:

同样要使用 pipeline ,也需要在 settings.py 中启用

#ITEM_PIPELINES = {
#    'myscrapy.pipelines.MyscrapyPipeline': 300,
#}
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


class MyscrapyPipeline(object):
    def process_item(self, item, spider):
        return item

settings.py

Scrapy设置(settings)提供了定制Scrapy组件的方法。可以控制包括核心(core),插件(extension),pipeline及spider组件。比如 设置Json Pipeliine、LOG_LEVEL等

结尾

关于 Scrapy 项目的基本点就讲到这里,另外公众号后台回复【scrapy课件】,有一个关于 Scrapy 的课件等着你哦,对于新手来说基本知识点都涵盖在内了,且易于理解


print('微信公众号搜索 "猿狮的单身日常" ,Java技术升级、虫师修炼,我们 不见不散!')
print('也可以扫下方二维码哦~')
猿狮的单身日常
上一篇下一篇

猜你喜欢

热点阅读