Item Pipeline

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

每个Item Pipeline都是实现了简单方法的Python类,比如决定此Item是丢弃而存储。以下是item pipeline的一些典型应用:

  • 验证爬取的数据(检查item包含某些字段,比如说name字段)
  • 查重(并丢弃)
  • 将爬取结果保存到文件或者数据库中

编写item

在items.py中进行编写

class JobBoleArticleItem(scrapy.Item):
title = scrapy.Field()
create_date = scrapy.Field()
praise_num = scrapy.Field()
collect_num = scrapy.Field()
comment_num = scrapy.Field()
front_image_url = scrapy.Field()

编写之后在提取文章逻辑里面进行实例化

    def parse_detail(self,response):
print("目前爬取的URL是:"+response.url)
#提取文章的具体逻辑
article_item = JobBoleArticleItem()
front_image_url = response.meta.get("front_image_url", "")
# 获取文章标题
title = response.css('.entry-header h1::text').extract()[0]
# 获取发布日期
create_date = response.css('.entry-meta .entry-meta-hide-on-mobile::text').extract()[0].strip().replace("·", "")
# 获取点赞数
praise_num = response.css('.vote-post-up h10::text').extract()[0]
# 获取收藏数
collect_num = response.css('.post-adds .bookmark-btn::text').extract()[0].split(" ")[1]
collect_match_re = re.match(r'.*?(\d+).*', collect_num)
if collect_match_re:
collect_num = int(collect_match_re.group(1))
else:
collect_num = 0
# 获取评论数
comment_num = response.css('.post-adds .hide-on-480::text').extract()[0]
comment_match_re = re.match(r'.*?(\d+).*', comment_num)
if comment_match_re:
comment_num = int(comment_match_re.group(1))
else:
comment_num = 0 content = response.css('div.entry').extract()[0] article_item["title"] = title
article_item["create_date"] =create_date
article_item["praise_num"] = praise_num
article_item["collect_num"] = collect_num
article_item["comment_num"] = comment_num
article_item["front_image_url"] = front_image_url yield article_item

最后调用yield article_item之后,article_item会传递到pipelines.py里面

编写pipelines

在pipelines.py文件中模板已经写好,但是如果要使之生效,需要修改settings.py文件,将ITEM_PIPELINES的注释去掉

在pipelines.py里面打断点进行调试,看article_item是否能传递尽来

如何将图片保存到本地

继续修改item,scrapy提供了一些方法,方便快速开发,修改settings.py

ITEM_PIPELINES = {
'EnterpriseSpider.pipelines.EnterprisespiderPipeline': 300,
'scrapy.pipelines.images.ImagesPipeline': 1,
}
IMAGES_URLS_FIELD = "front_image_url"
project_dir = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(project_dir, "images")

'scrapy.pipelines.images.ImagesPipeline': 1-------设置scrapy自带的普票保存方法,后面设置数字是流经管道的顺序,数字小的先流经

IMAGES_URLS_FIELD = "front_image_url"------从item中提取图片的URL,前面的IMAGES_URLS_FIELD是固定写法

project_dir = os.path.abspath(os.path.dirname(__file__)):获取当前项目的路径

IMAGES_STORE = os.path.join(project_dir, "images"):设置图片存储的路径

此时运行我们的main看是否能将图片保存

报错,没有PIL这个模块,这个是与图片文件相关的库,我们没有按照,所以报错,在虚拟环境中安装PIL模块

(scrapyenv) E:\Python\Envs>pip install -i https://pypi.douban.com/simple pillow

安装之后重新运行程序,此时又报另一个错误

这个因为item传递到pipline的时候,下面的front_image_url 会被当做数组处理,但是我们在业务逻辑处理时候只是把他当做一个值进行处理

IMAGES_URLS_FIELD = "front_image_url"

修改业务处理逻辑

        article_item["title"] = title
article_item["create_date"] =create_date
article_item["praise_num"] = praise_num
article_item["collect_num"] = collect_num
article_item["comment_num"] = comment_num
article_item["front_image_url"] = [front_image_url] yield article_item

修改完之后在运行程序,此时爬取的图片成功保存到images文件夹下面

既然图片已经保存到本地了,那么是否可以提取出路径,是否能把item里面的front_image_url与本地路径绑定在一起,此时我们需要定义一个自己pipeline,重载ImagesPipeline 中的item_completed

方法。

class ArticleImagePipeline(ImagesPipeline):
def item_completed(self, results, item, info):
pass

此时在修改settings.py文件,设置问我们自定义的图片处理pipeline

ITEM_PIPELINES = {
'EnterpriseSpider.pipelines.EnterprisespiderPipeline': 300,
# 'scrapy.pipelines.images.ImagesPipeline': 1,
'EnterpriseSpider.pipelines.ArticleImagePipeline': 1,
}

打断点进行调试

重写item_completed方法

class ArticleImagePipeline(ImagesPipeline):
def item_completed(self, results, item, info):
for ok, value in results:
image_file_path = results["path"]
item["front_image_url"] = image_file_path
return item

保存到JSON

class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = codecs.open('article.json', 'w', encoding='utf-8') def process_item(self,item,spider):
lines = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(lines)
return item def spider_closed(self,spider):
self.file.close()

保存到MySQL

同步保存

class MysqlPipeline(object):
def __init__(self):
self.conn = MySQLdb.connect('127.0.0.1', 'root', '', 'article', charset='utf8', use_unicode=True)
self.cursor = self.conn.cursor() def process_item(self,item,spider):
insert_sql = '''
insert into jobbole(title,create_date,front_image_url,praise_num,collect_num,comment_num,url,url_object_id)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
''' self.cursor.execute(insert_sql, (item['title'], item['create_date'], item["front_image_url"],
item["praise_num"], item["collect_num"], item["comment_num"],
item["url"], item["url_object_id"]))
self.conn.commit()

异步保存

class MysqlTwistedPipeline(object):

    def __init__(self, dbpool):
self.dbpool = dbpool @classmethod
def from_settings(cls, settings):
dbparams = dict(
host=settings['MYSQL_HOST'],
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
password=settings['MYSQL_PASSWORD'],
charset='utf8',
cursorclass=MySQLdb.cursors.DictCursor,
use_unicode=True,
)
dbpool = adbapi.ConnectionPool("MySQLdb", **dbparams)
return cls(dbpool) def process_item(self,item,spider):
#使用twisted将mysql插入变成异步插入
query = self.dbpool.runInteraction(self.db_insert, item)
query.addErrback(self.handler_error, item, spider) def handler_error(self,failuer,item,spider):
#处理异步插入的异常
print(failuer) def db_insert(self,cursor,item):
insert_sql = '''
insert into jobbole(title,create_date,front_image_url,praise_num,collect_num,comment_num,url,url_object_id)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
''' cursor.execute(insert_sql, (item['title'], item['create_date'], item["front_image_url"],
item["praise_num"], item["collect_num"], item["comment_num"],
item["url"], item["url_object_id"]))

爬取伯乐在线文章(四)将爬取结果保存到MySQL的更多相关文章

  1. 第三天,爬取伯乐在线文章代码,编写items.py,保存数据到本地json文件中

        一. 爬取http://blog.jobbole.com/all-posts/中的所有文章     1. 编写jobbole.py简单代码 import scrapy from scrapy. ...

  2. 爬取伯乐在线文章(五)itemloader

    ItemLoader 在我们执行scrapy爬取字段中,会有大量的CSS或是Xpath代码,当要爬取的网站多了,要维护起来很麻烦,为解决这类问题,我们可以根据scrapy提供的loader机制. 导入 ...

  3. 爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容

    爬取说明 以单个页面为例,如:http://blog.jobbole.com/110287/ 我们可以提取标题.日期.多少个评论.正文内容等 Xpath介绍 1. xpath简介 (1) xpath使 ...

  4. Scrapy爬取伯乐在线文章

    首先搭建虚拟环境,创建工程 scrapy startproject ArticleSpider cd ArticleSpider scrapy genspider jobbole blog.jobbo ...

  5. scrapy爬取伯乐在线文章数据

    创建项目 切换到ArticleSpider目录下创建爬虫文件 设置settings.py爬虫协议为False 编写启动爬虫文件main.py

  6. python爬虫scrapy框架——爬取伯乐在线网站文章

    一.前言  1. scrapy依赖包: 二.创建工程 1. 创建scrapy工程: scrapy staratproject ArticleSpider 2. 开始(创建)新的爬虫: cd Artic ...

  7. 爬虫实战——Scrapy爬取伯乐在线所有文章

    Scrapy简单介绍及爬取伯乐在线所有文章 一.简说安装相关环境及依赖包 1.安装Python(2或3都行,我这里用的是3) 2.虚拟环境搭建: 依赖包:virtualenv,virtualenvwr ...

  8. Scrapy爬取伯乐在线的所有文章

    本篇文章将从搭建虚拟环境开始,爬取伯乐在线上的所有文章的数据. 搭建虚拟环境之前需要配置环境变量,该环境变量的变量值为虚拟环境的存放目录 1. 配置环境变量 2.创建虚拟环境 用mkvirtualen ...

  9. python爬虫实战(七)--------伯乐在线文章(模版)

    相关代码已经修改调试成功----2017-4-21 一.说明 1.目标网址:伯乐在线 2.实现:如图字段的爬取 3.数据:存放在百度网盘,有需要的可以拿取 链接:http://pan.baidu.co ...

随机推荐

  1. vue(四)-vuex与组件联合使用

    官方定义: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.我的理解就是,vuex就是前端的数据库. 1.首先核心是store,是个仓库,包含着state,因此第一步需要新建一个sto ...

  2. SpringBoot设置文件上传大小限制--默认为1M

    SpringBoot默认上传文件大小不能超过1MB,超过之后会报以下异常:org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeL ...

  3. CSS3布局之多列布局columns详解

    columns语法:columns:[ column-width ] || [ column-count ]设置或检索对象的列数和每列的宽度 其中:[ column-width ]:设置或检索对象每列 ...

  4. POJ1275 Cashier Employment(差分约束)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9078   Accepted: 3515 Description A sup ...

  5. 【读书笔记】iOS-库

    一,OS X和iOS自带一些标准的C程序库和操作系统相关的特殊性.在MAC和iOS的世界里,静态库采用.a扩展名(静态对象代码库存档),动态加载库采用.dylib扩展名.如果开发人员来自于Linux世 ...

  6. Apache Beam WordCount编程实战及源码解读

    概述:Apache Beam WordCount编程实战及源码解读,并通过intellij IDEA和terminal两种方式调试运行WordCount程序,Apache Beam对大数据的批处理和流 ...

  7. 归并排序(MergeSort)和快速排序(QuickSort)的一些总结问题

    归并排序(MergeSort)和快速排序(QuickSort)都是用了分治算法思想. 所谓分治算法,顾名思义,就是分而治之,就是将原问题分割成同等结构的子问题,之后将子问题逐一解决后,原问题也就得到了 ...

  8. Windows 不能在本地计算机启动 OracleDBConsoleorcl的问题解决方法

    解决步骤如下: 1.开始->运行cmd 2.执行 emctl start dbconsole 输入:C:\Documents and Settings\xcl>emctl start db ...

  9. awesomium_v1.6.6_sdk 百度云下载地址

    awesomium的官网已经关闭很久了,所以找不到正规的下载地址. 而csdn上面的又收费.所以这里提供一个不收费的百度云的下载地址给大家. 不足就是不是1.7版本,所以对于某些有特殊用途的满足不了了 ...

  10. JHipster生成单体架构的应用示例

    本文演示如何用JHipster生成一个单体架构风格的应用. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用名:app1 实体名:role 主机IP:192.168.2 ...