-
Python爬虫基础讲解(二十七):scrapy 框架—ltem和scrapy.Request
ltem
Item是保存爬取数据的容器,它的使用方法和字典类似。不过,相比字典,Item提供了额外的保护机制,可以避免拼写错误或者定义字段错误。
创建Item需要继承scrapy.Item类,并且定义类型为scrapy.Field的字段。在创建项目开始的时候Item文件是这样的。
import scrapy class Tutorial1tem(scrapy.Item): #define the fields for your item here 7ike:#参照下面这个参数定义你的字段 #name = scrapy.Fie1d() pass
在保存数据的时候可以每次初始化一个字典等格式,但是最方便,最好的保存方式就是使用Scrapy自带的ltem数据结构了。
我们学习了从页面中提取数据的方法,接下来学习如何封装爬取到的数据。应该用怎样的数据结构来维护这些零散的信息字段呢?最容易想到是使用Python字典(dict)。
回顾之前的代码
class Quotesspider(scrapy.spider): name = 'quotes' a1lowed_domains = ['toscrape.com'] start_ur1s = ['http: //quotes.toscrape.com/'] def parse(self,response): quotes = response.css( '.quote ' ) for quote in quotes : text = quote.css('.text: :text ').get() author = quote.css( '.author : :text ').get() tags = quote.css( '.tag : :text ' ).getall() yield { 'text':text, 'author':author, 'tags ' : tags, }
在该案例中,我们便使用了Python字典存储一本书的信息,但字典可能有以下缺点:
(1)无法一目了然地了解数据中包含哪些字段,影响代码可读性。
(2缺乏对字段名字的检测,容易因程序员的笔误而出错。
(3)不便于携带元数据(传递给其他组件的信息)。
ltem和Field
Scrapy提供了以下两个类,用户可以使用它们自定义数据类(如书籍信息),封装爬取到的数据:
1. ltem基类
数据结构的基类,在items.py中定义数据结构时,需要继承自该基类。
2. Field类
用来描述自定义数据类包含哪些字段(如name、price等)。
自定义一个数据类,只需继承ltem,并创建一系列Field对象的类属性即可。
以定义书籍信息quote为例,它包含个字段,分别为书的名字text、author和tags,代码如下:
#特殊的字典结构可以在scrapy中传递数据 class TutorialItem(scrapy.Item): #Field字段 #就是类似于产生一个类似字典格式的数据拥有字典的一些属性 #字段默认为空 #我们可以通过实例化像着键赋值但是如果没有写这个键就不能赋值但是字典可以 text = scrapy. Field() author = scrapy.Fie1d() tags = scrapy . Fie1d()
ltem支持字典接口,因此Tutorialltem在使用上和Python字典类似。
对字段进行赋值时,Tutorialltem内部会对字段名进行检测,如果赋值一个没有定义的字段,就会抛出异常(防止因用户粗心而导致错误)
scrapy.Request
Request和Response 对象,用于爬网网站。
Request对象用来描述一个HTTP请求,下面是其构造器方法的参数列表:
Request(url,ca11back=None,method='GET', headers=None,body=None, cookies=None,meta=None,encoding='utf-8 ',priority=O, dont_filter=False,errback=None,flags=None,cb_kwargs=None)
-
url(字符串) -此请求的URL
-
callback (callable)-将以请求的响应(一旦下载)作为第一个参数调用的函数。有关更多信息,请参见下面的将其他数据传递给回调函数。如果"请求'未指定回调,parse()则将使用"Spider"方法。请注意,如果在处理过程中引发异常,则会调用errback.
-
method(字符串)-此请求的HTTP方法。默认为‘GET'。
-
meta (dict) - Request.meta属性的初始值。如果给出,则在此参数中传递的字典将被浅表复制。
-
headers (dict)-请求头。dict值可以是字符串(对于单值标头)或列表(对于多值标头)。如果None作为值传递,则将根本不发送HTTP标头。
c1ass Quotesspider(scrapy.spider): name = 'quotes_3' allowed_domains = ['toscrape.com'] start__ur1s = ['http://quotes.toscrape.com/'] def parse(self,response): quotes = response.css( '.quote ' ) for quote in quotes: text = quote.css( '.text: :text ' ).get() author = quote.css( '.author : :text ' ).get() tags = quote.css( '.tag : :text ' ). geta11() yield Qd01QuotesItem(text=text,author=author,tags=tags) next_page = response.css( '.next a: :attr(href) ' ).get() if next_page: next__ur1 = 'http: //quotes.toscrape.com' + next_page yield scrapy. Request(next_url, cal7back=self.parse)