Scrapy scrapy.Item & pipeline

scrapy.Item
可以将数据以json的形式存储起来
为了定义常用的输出数据,Scrapy提供了Item 类。 Item 对象是种简单的容器,保存了爬取到得数据。 其提供了 类似于词典(dictionary-like) 的API以及用于声明可用字段的简单语法。

scrapy startproject tutorial

声明Item:修改items.py

import scrapy

class TutorialItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()

添加爬取的文件myfirst.py

# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import TutorialItem

class muhe(scrapy.Spider):
    name = "mutian"

    def start_requests(self):
        urls = [
            'http://lab.scrapyd.cn/page/1/'
        ]

        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        print("-----------")
        print(response.status)
        print(response.xpath("//title"))
        print("-----------")
        #selector = response.xpath("//ul[@class='tags-list']/li/a/text()")
        selector = response.xpath("//ul[@class='tags-list']/li/a")
        for sel in selector:
            item = TutorialItem()
            _title = sel.xpath("text()").extract_first().strip()
            _link = sel.xpath("@href").extract_first().strip()
            print(_title, _link)
            item['title'] = _title
            item['link'] = _link
            yield item

D:\work\tutorial>scrapy crawl mutian -o items_1.json

运行结果生成items_1.json

[
{"title": "人生", "link": "http://lab.scrapyd.cn/tag/%E4%BA%BA%E7%94%9F/"},
{"title": "励志", "link": "http://lab.scrapyd.cn/tag/%E5%8A%B1%E5%BF%97/"},
{"title": "爱情", "link": "http://lab.scrapyd.cn/tag/%E7%88%B1%E6%83%85/"},
{"title": "王尔德", "link": "http://lab.scrapyd.cn/tag/%E7%8E%8B%E5%B0%94%E5%BE%B7/"},
{"title": "智慧", "link": "http://lab.scrapyd.cn/tag/%E6%99%BA%E6%85%A7/"},
{"title": "泰戈尔", "link": "http://lab.scrapyd.cn/tag/%E6%B3%B0%E6%88%88%E5%B0%94/"},
{"title": "绝世好词", "link": "http://lab.scrapyd.cn/tag/%E7%BB%9D%E4%B8%96%E5%A5%BD%E8%AF%8D/"},
{"title": "木心", "link": "http://lab.scrapyd.cn/tag/%E6%9C%A8%E5%BF%83/"},
{"title": "艺术", "link": "http://lab.scrapyd.cn/tag/%E8%89%BA%E6%9C%AF/"},
{"title": "名画", "link": "http://lab.scrapyd.cn/tag/%E5%90%8D%E7%94%BB/"},
{"title": "生活", "link": "http://lab.scrapyd.cn/tag/%E7%94%9F%E6%B4%BB/"},
{"title": "", "link": "http://lab.scrapyd.cn/tag/%E8%AF%8D/"},
{"title": "返回首页", "link": "http://lab.scrapyd.cn"},
{"title": "SCRAPY中文社区", "link": "http://bbs.scrapyd.cn"},
{"title": "SCRAPY中文网", "link": "http://www.scrapyd.cn"}
]

 

运行过程生成的文件可能会有中文乱码
Scrapy爬取到中文数据默认是 Unicode编码的,于是显示是这样的:
{"title": "\u4eba\u751f", "link": "http://lab.scrapyd.cn/tag/%E4%BA%BA%E7%94%9F/"},
{"title": "\u52b1\u5fd7", "link": "http://lab.scrapyd.cn/tag/%E5%8A%B1%E5%BF%97/"},
需在settings.py文件中增加一行,导出时强制为'utf-8'即可(default值为Unicode)

FEED_EXPORT_ENCODING = 'utf-8

 

Pipeline

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

在之前代码基础上修改pipelines.py

from scrapy.exceptions import DropItem
import json

class TutorialPipeline(object):
    def process_item(self, item, spider):
        if len(item['title']) < 3:
            return item
        else:
            raise DropItem("item title length >=3  %s" % item)

class DuplicatesPipeline(object):
    def __init__(self):
        self.ids_seen = set()
    def process_item(self, item, spider):
        if item['title'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['title'])
            return item

修改settings.py配置使用ITEM_PIPELINES 

# 启用一个Item Pipeline组件,你必须将它的类添加到 ITEM_PIPELINES 配置
# 分配给每个类的整型值,确定了他们运行的顺序,item按数字从低到高的顺序,通过pipeline,
# 通常将这些数字定义在0-1000范围内。
ITEM_PIPELINES = {
    'tutorial.pipelines.TutorialPipeline': 300,
    'tutorial.pipelines.DuplicatesPipeline': 301,
}

scrapy crawl mutian -o items_2.json

[
{"title": "人生", "link": "http://lab.scrapyd.cn/tag/%E4%BA%BA%E7%94%9F/"},
{"title": "励志", "link": "http://lab.scrapyd.cn/tag/%E5%8A%B1%E5%BF%97/"},
{"title": "爱情", "link": "http://lab.scrapyd.cn/tag/%E7%88%B1%E6%83%85/"},
{"title": "智慧", "link": "http://lab.scrapyd.cn/tag/%E6%99%BA%E6%85%A7/"},
{"title": "木心", "link": "http://lab.scrapyd.cn/tag/%E6%9C%A8%E5%BF%83/"},
{"title": "艺术", "link": "http://lab.scrapyd.cn/tag/%E8%89%BA%E6%9C%AF/"},
{"title": "名画", "link": "http://lab.scrapyd.cn/tag/%E5%90%8D%E7%94%BB/"},
{"title": "生活", "link": "http://lab.scrapyd.cn/tag/%E7%94%9F%E6%B4%BB/"},
{"title": "", "link": "http://lab.scrapyd.cn/tag/%E8%AF%8D/"}
]

items_2.json对比items_1.json  title长度<3 才显示,其它的都被丢弃

posted @ 2019-01-26 16:48  牧 天  阅读(205)  评论(0)    收藏  举报