Scrapy笔记06- Item Pipeline

当一个item被蜘蛛爬取到之后会被发送给Item Pipeline,然后多个组件按照顺序处理这个item。 每个Item Pipeline组件其实就是一个实现了一个简单方法的Python类。他们接受一个item并在上面执行逻辑,还能决定这个item到底是否还要继续往下传输,如果不要了就直接丢弃。

使用Item Pipeline的常用场景:

  • 清理HTML数据
  • 验证被抓取的数据(检查item是否包含某些字段)
  • 重复性检查(然后丢弃)
  • 将抓取的数据存储到数据库中

编写自己的Pipeline

定义一个Python类,然后实现方法process_item(self, item, spider)即可,返回一个字典或Item,或者抛出DropItem异常丢弃这个Item。

或者还可以实现下面几个方法:

  • open_spider(self, spider) 蜘蛛打开的时执行
  • close_spider(self, spider) 蜘蛛关闭时执行
  • from_crawler(cls, crawler) 可访问核心组件比如配置和信号,并注册钩子函数到Scrapy中

Item Pipeline示例

价格验证

我们通过一个价格验证例子来看看怎样使用

from scrapy.exceptions import DropItem

class PricePipeline(object):

    vat_factor = 1.15

    def process_item(self, item, spider):
if item['price']:
if item['price_excludes_vat']:
item['price'] = item['price'] * self.vat_factor
return item
else:
raise DropItem("Missing price in %s" % item)

将item写入json文件

下面的这个Pipeline将所有的item写入到一个单独的json文件,一行一个item

import json

class JsonWriterPipeline(object):

    def __init__(self):
self.file = open('items.jl', 'wb') def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item

将item存储到MongoDB中

这个例子使用pymongo来演示怎样讲item保存到MongoDB中。 MongoDB的地址和数据库名在配置中指定,这个例子主要是向你展示怎样使用from_crawler()方法,以及如何清理资源。

import pymongo

class MongoPipeline(object):

    collection_name = 'scrapy_items'

    def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db @classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
) def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db] def close_spider(self, spider):
self.client.close() def process_item(self, item, spider):
self.db[self.collection_name].insert(dict(item))
return item

重复过滤器

假设我们的item里面的id字典是唯一的,但是我们的蜘蛛返回了多个相同id的item

from scrapy.exceptions import DropItem

class DuplicatesPipeline(object):

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

激活一个Item Pipeline组件

你必须在配置文件中将你需要激活的Pipline组件添加到ITEM_PIPELINES

ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 300,
'myproject.pipelines.JsonWriterPipeline': 800,
}

后面的数字表示它的执行顺序,从低到高执行,范围0-1000

Feed exports

这里顺便提下Feed exports,一般有的爬虫直接将爬取结果序列化到文件中,并保存到某个存储介质中。只需要在settings里面设置几个即可:

* FEED_FORMAT= json # json|jsonlines|csv|xml|pickle|marshal
* FEED_URI= file:///tmp/export.csv|ftp://user:pass@ftp.example.com/path/to/export.csv|s3://aws_key:aws_secret@mybucket/path/to/export.csv|stdout:
* FEED_EXPORT_FIELDS = ["foo", "bar", "baz"] # 这个在导出csv的时候有用

请求和响应

Scrapy使用RequestResponse对象来爬取网站。Request对象被蜘蛛生成,然后被传递给下载器,之后下载器处理这个Request后返回Response对象,然后返回给生成Request的这个蜘蛛。

给回调函数传递额外的参数

Request对象生成的时候会通过关键字参数callback指定回调函数,Response对象被当做第一个参数传入,有时候我们想传递额外的参数,比如我们构建某个Item的时候,需要两步,第一步是链接属性,第二步是详情属性,可以指定Request.meta

def parse_page1(self, response):
item = MyItem()
item['main_url'] = response.url
request = scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
request.meta['item'] = item
return request def parse_page2(self, response):
item = response.meta['item']
item['other_url'] = response.url
return item

Request子类

Scrapy为各种不同的场景内置了很多Request子类,你还可以继承它自定义自己的请求类。

FormRequest这个专门为form表单设计,模拟表单提交的示例

return [FormRequest(url="http://www.example.com/post/action",
formdata={'name': 'John Doe', 'age': ''},
callback=self.after_post)]

我们再来一个例子模拟用户登录,使用了FormRequest.from_response()

import scrapy

class LoginSpider(scrapy.Spider):
name = 'example.com'
start_urls = ['http://www.example.com/users/login.php'] def parse(self, response):
return scrapy.FormRequest.from_response(
response,
formdata={'username': 'john', 'password': 'secret'},
callback=self.after_login
) def after_login(self, response):
# check login succeed before going on
if "authentication failed" in response.body:
self.logger.error("Login failed")
return # continue scraping with authenticated session...

Response子类

一个scrapy.http.Response对象代表了一个HTTP相应,通常是被下载器下载后得到,并交给Spider做进一步的处理。Response也有很多默认的子类,用于表示各种不同的响应类型。

  • TextResponse 在基本Response类基础之上增加了编码功能,专门用于二进制数据比如图片、声音或其他媒体文件
  • HtmlResponse 此类是TextResponse的子类,通过查询HTML的meta http-equiv属性实现了编码自动发现
  • XmlResponse 此类是TextResponse的子类,通过查询XML声明实现编码自动发现
 

Scrapy笔记06- Item Pipeline的更多相关文章

  1. scrapy框架中Item Pipeline用法

    scrapy框架中item pipeline用法 当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的pyt ...

  2. Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

  3. Python之爬虫(十八) Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

  4. 二、Item Pipeline和Spider-----基于scrapy取校花网的信息

    Item Pipeline 当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item. 每个Item Pipeline ...

  5. Scrapy爬虫框架第七讲【ITEM PIPELINE用法】

    ITEM PIPELINE用法详解:  ITEM PIPELINE作用: 清理HTML数据 验证爬取的数据(检查item包含某些字段) 去重(并丢弃)[预防数据去重,真正去重是在url,即请求阶段做] ...

  6. Scrapy框架-Item Pipeline

    目录 1. Item Pipeline 3. 完善之前的案例: 3.1. item写入JSON文件 3.2. 启用一个Item Pipeline组件 3.3. 重新启动爬虫 1. Item Pipel ...

  7. scrapy item pipeline

    item pipeline process_item(self, item, spider) #这个是所有pipeline都必须要有的方法在这个方法下再继续编辑具体怎么处理 另可以添加别的方法 ope ...

  8. Scrapy学习篇(七)之Item Pipeline

    在之前的Scrapy学习篇(四)之数据的存储的章节中,我们其实已经使用了Item Pipeline,那一章节主要的目的是形成一个笼统的认识,知道scrapy能干些什么,但是,为了形成一个更加全面的体系 ...

  9. 爬虫框架Scrapy之Item Pipeline

    Item Pipeline 当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item. 每个Item Pipeline ...

随机推荐

  1. 日志模块log4js的配置说明

    1:先安装log4js模块 npm install log4js 目前安装的版本信息:"log4js": "^3.0.5" 2:引用及配置 var log4js ...

  2. .NET Core:过滤器

    过滤器的作用是在 Action 方法执行前或执行后做一些加工处理.使用过滤器可以避免Action方法的重复代码.功能上更贴合业务的使用过滤器. 在Startup中的ConfigureServices方 ...

  3. Intellij-Cannot download Sources解决方法

    当你点击Dowload Sources的时候它会报一个错误 提示你不能下载源代码,这个时候你可以打开下方的命令窗口 然后 进入到项目根路径后  使用mvn dependency:resolve -Dc ...

  4. Qt Quick 组件与动态对象

    博客24## 一.Components(组件) Component 是由 Qt 框架或开发者封装好的.只暴露了必要接口的 QML 类型,可以重复利用.一个 QML 组件就像一个黑盒子,它通过属性.信号 ...

  5. Github问题:fatal: unable to access 'https://github.com/LIU-HONGYANG/Algorithm.git/': The requested URL returned error: 403

    在向服务器push之后,出现如下问题: The requested URL returned error: 403 解决路径如下: 参考文章: https://stackoverflow.com/qu ...

  6. oracle 数据库创建用户并授权

    oracle 数据库创建用户并授权 备注: userName 为用户名,123456 为密码 drop user userName cascade; create user userName iden ...

  7. 发送邮件报错javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed

    关于使用javaMail发送邮件报错:javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multip ...

  8. vue组件、自定义指令、路由

    1.vue组件 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  9. 前端学习:JS学习总结(图解)

    前端学习:JS学习总结(图解) JS的代码笔记 JS比HTML和CSS的知识点要多的多,下面分几段来介绍其内容... 为了能让大家更好的检索,前面的图解是整个JS的概括,后面的才是知识点... 旁边就 ...

  10. C# FastReport .NET打印

    引用DLL : FastReport.dll FastReport.Report sender = new FastReport.Report(); try { sender.Load("f ...