如何使用Scrapy项目

95 阅读2分钟

How To Use Scrapy Items

Scrapy中的Item是一个从网站上提取的数据点的逻辑分组,它代表了现实世界的事物。你不必马上使用Scrapy项目,正如我们在早期的Scrapy教程中看到的那样。你可以简单地在页面元素被提取出来后,按你的意愿处理这些数据。项目提供了更好地结构化你搜刮的数据的能力,以及用[项目加载器]而不是直接用默认的Spider parse()方法来处理数据。让我们在这里多了解一点关于Scrapy项目的信息。

定义Scrapy项目

如果我们打开Scrapy项目中的items.py,会有一些启动代码来帮助我们。它可能看起来像下面这样,尽管它是基于你的项目命名的。

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

import scrapy


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

为了理解如何定义项目,让我们看看我们[Scrapy项目]的原始代码。

import scrapy


class BooksSpider(scrapy.Spider):
    name = 'books'
    allowed_domains = ['books.toscrape.com']
    start_urls = ['http://books.toscrape.com/']

    def parse(self, response):
        for book in response.xpath('//article'):
            yield {
                'booktitle': book.xpath('.//a/text()').get(),
                'bookrating': book.xpath('.//p').attrib['class'],
                'bookprice': book.xpath('.//div[2]/p/text()').get(),
                'bookavailability': book.xpath('.//div[2]/p[2]/i/following-sibling::text()').get().strip()
            }

        next_page = response.css('.next a').attrib['href']
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

我们想在items.py中添加高亮的行作为项目。我们可以通过编写以下代码来更新 items.py 以反映这一点。

items.py

import scrapy


class BookstoscrapeItem(scrapy.Item):
    booktitle = scrapy.Field()
    bookrating = scrapy.Field()
    bookprice = scrapy.Field()
    bookavailability = scrapy.Field()

关于声明项目的一点是,如果我们声明了一个字段,并不意味着我们必须在每个蜘蛛上填写它,或者甚至完全使用它。我们可以添加任何看起来合适的字段,如果需要的话,我们可以在以后随时纠正它们。

更新Spider代码

通过为我们的项目类定义这些字段,意味着我们可以使用该类的一个对象在蜘蛛中加载数据。语法与不使用Item时有些不同,新定义的类需要被导入Spider类中。突出显示的几行代码显示了如何导入新的Item类,从它那里实例化一个Item对象,填充每个字段,然后产生填充的Item对象。

import scrapy
from bookstoscrape.items import BookstoscrapeItem


class BooksSpider(scrapy.Spider):
    name = 'books'
    allowed_domains = ['books.toscrape.com']
    start_urls = ['http://books.toscrape.com/']

    def parse(self, response):
        item = BookstoscrapeItem()
        for book in response.xpath('//article'):
            item['booktitle'] = book.xpath('.//a/text()').get()
            item['bookrating'] = book.xpath('.//p').attrib['class']
            item['bookprice'] = book.xpath('.//div[2]/p/text()').get()
            item['bookavailability'] = book.xpath('.//div[2]/p[2]/i/following-sibling::text()').get().strip()

            yield item

        next_page = response.css('.next a').attrib['href']
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

运行Spider

现在用scrapy crawl books运行spider会产生与我们第一次开始这个项目时完全相同的结果,即使没有定义Item。那么,如果程序的运行是一样的,我们为什么还要做这些工作来定义这些项目呢?答案是,通过建立Items类并加以利用,我们可以在Scrapy中释放出许多新的功能,比如在输出或存储之前使用Item Loaders来清理和消毒数据。