itemLoader

能够让代码更加易于维护

三种方法

addValue(Item参数名,值) 给参数添加值,比如response中的url,或者上一个方法yield传递的值
addXpath(Item参数名,xpath语法) 匹配Xpath选择器
addCss(Item参数名,css语法) 匹配css选择器

导包

from ``scrapy.loader ``import ``ItemLoader
from scrapy.loader.processors import MapCompose,TakeFirst,Join,Identity

使用案例

item顾名思义就是一个item类
response和parse的形参response一样,都是一个响应的对象,里面会有网址等等一些信息

  1. # ItemLoader(实例化item,response)
  2. item_loader = ItemLoader(item=CnblogItem(), response=response)
  3. item_loader.add_xpath("title", '//*[@id="news_title"]/a/text()')
  4. item_loader.add_xpath("create_date", '//*[@id="news_info"]/span[2]/text()')
  5. item_loader.add_xpath("content", '//*[@id="news_content"]')
  6. item_loader.add_xpath("tags", '//*[@id="link_source2"]/text()')
  7. item_loader.add_xpath("totalView", '//*[@id="News_TotalView"]')
  8. item_loader.add_value("url", response.url)
  9. item_loader.add_value("front_image_url", response.meta.get("front_image_url", ""))
  10. # 将配置好的item再赋值给一个新对象
  11. CnblogItemEntity = item_loader.load_item()

运行一下

所有值都被处理成了数组的形式
image.png

如何处理

TakeFirst

我们已经拿到List了,但是我们常常不需要list,因为像content内容,一篇文章就一个文章内容,不会出现多个,所以怎么样去掉中括号让它回归成一个字符串。那么就用到Take_first,和extract_first道理一样

  1. title = scrapy.Field(
  2. output_processor=TakeFirst()
  3. )

MapCompose

我们把需要定制的逻辑都封装成方法,然后通过MapCompose进行调用,这个item属性在生成的时候就自动会调用方法进行参数处理。需要注意的是,这个定制方法(add_Article)形参是value,这个形参就是我们爬到的数据,一般针对这个形参进行处理。

  1. def add_Article(value):
  2. return value + 'bobby'
  3. title = scrapy.Field(
  4. input_processor=MapCompose(add_Article),
  5. )

Identity

Identity方法让数据回归到原先的list。比如我们做了默认操作,也就是下面的【继承ItemLoader】,将所有数组都默认处理成了字符串。但图片路径是不允许字符串的,只有数组scrapy才识别,否则会报错,那么就需要用到Identity

  1. front_image_url = scrapy.Field(
  2. output_processor=Identity()
  3. )

Join

它可以把一个数组做成一个按照间隔符拼接的字符串,比如[1,2,3,4] 如果我们想去掉数组中括号,保留”1,2,3,4”字符串结果,Join可以帮我们实现

  1. tag = scrapy.Field(
  2. output_processor=Join(separator=",")
  3. )

继承ItemLoader

不直接用ItemLoader,而是继承ItemLoader,这样我们就可以做定制化处理,比如,直接默认每一个数据爬过来就提取数组中第一个字符串。那我们进行如下操作即可

  1. class ArticleItemLoader(ItemLoader):
  2. default_output_processor = TakeFirst()