The main goal in scraping is to extract structured data from unstructured
sources, typically, web pages. Scrapy spiders can return the extracted data
as Python dicts. While convenient and familiar, Python dicts lack structure:
it is easy to make a typo in a field name or return inconsistent data,
especially in a larger project with many spiders.

To define common output data format Scrapy provides the Item class.
Item objects are simple containers used to collect the scraped data.
They provide a dictionary-like API with a convenient syntax for declaring
their available fields.

Field objects are used to specify metadata for each field. For
example, the serializer function for the last_updated field illustrated in
the example above.

You can specify any kind of metadata for each field. There is no restriction on
the values accepted by Field objects. For this same
reason, there is no reference list of all available metadata keys. Each key
defined in Field objects could be used by a different component, and
only those components know about it. You can also define and use any other
Field key in your project too, for your own needs. The main goal of
Field objects is to provide a way to define all field metadata in one
place. Typically, those components whose behaviour depends on each field use
certain field keys to configure that behaviour. You must refer to their
documentation to see which metadata keys are used by each component.

It’s important to note that the Field objects used to declare the item
do not stay assigned as class attributes. Instead, they can be accessed through
the Item.fields attribute.

The Field class is just an alias to the built-in dict class and
doesn’t provide any extra functionality or attributes. In other words,
Field objects are plain-old Python dicts. A separate class is used
to support the item declaration syntax
based on class attributes.