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. 推荐一款健康App 多喝水,引领全民时尚喝水生活习惯

    推荐一款健康App 多喝水,引领全民时尚喝水生活习惯 1 介绍 多喝水,一款鼓励大众喝水的APP.我们倡导大众健康生活,培养人们爱喝水的习惯,让每一次喝水,都能产生价值,让人们在喝水的同时,可享受赚钱 ...

  2. 从头学一次J2EE笔记

    1.在Servlet3.5规范之前,Java Web 应用的绝大部分组件都通过web.xml 文件来配置管理, Servlet3.0 规范可通过Annotation来配置管理Web组件,因此web.x ...

  3. etcd v3 ssl 集群添加新节点

    集群搭建 下面只用同一台服务器进行三个成员节点的开启 节点1 ./etcd --name cd0 --initial-advertise-peer-urls http://127.0.0.1:2380 ...

  4. Task和async/await详解

    一.什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务 ...

  5. RC4算法

    RC4算法简介:https://baike.baidu.com/item/RC4%E7%AE%97%E6%B3%95/9686396?fr=aladdin RC4算法java实现: /** * RC4 ...

  6. java -jar 时指定内存大小

    java -jar -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M car.jar 说明: 1.堆内存:最小1024M,最大153 ...

  7. 一个JS正则的字符串替换函数

    直接上函数吧  不废话 function replacestring(oldstr,newstr,text) { var exp = new RegExp(oldstr,'g'); var c=tex ...

  8. 输入www.baidu.com会发生什么

    1. 浏览器接收域名 2. 发送域名给DNS,请求解析出www.baidu.com的IP地址 中文名字是域名系统服务器,一般位于ISP(互联网服务提供商,比如我们熟知的联通.移动.电信等) 中.浏览器 ...

  9. Winfrom devexpress 通用权限框架

    毕业到现在也快两年了,手上的项目也有好几个,但总感觉不是狠理想,近来把手上杂七杂八的项目整理了一下,结合各个项目的优点,重新开发了一套winfrom+devexpress 通用权限(CS)框架(BS版 ...

  10. 使用GitHub/码云/Git个性化设置

    参考链接:https://www.liaoxuefeng.com/wiki/896043488029600/900937935629664 这似乎很可笑,我还从来没有想过为一个网站的使用方法写一篇来记 ...