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. 微信小程序之发送模板消息(通过openid推送消息给用户)

    一.获取access_token access_token是接口调用的凭证,目前有效期为两个小时,需要定时刷新,重复获取将导致上次获取的access_token失效.(注:不建议每次调用需要acces ...

  2. 弹性盒模型flex

    一.flex flex是flexible box的缩写,意为“弹性布局”: 定义弹性布局 display:flex; box{ display:flex; } 二.基本定义 我只简单的说一下容器和项目 ...

  3. Django的模板系统

    一.语法 关于模板渲染只需要记住两种特殊符号(语法): {{ }} 和 {% %}  (变量相关用{{ }}  逻辑相关用{% %}) 二.变量 在Django的模板语言中按照{{ 变量名 }}来使用 ...

  4. 2018-08-11 中文代码示例之Spring Boot 2.0.3问好

    上次试用Spring Boot还是两年前: 中文代码示例之Spring Boot 1.3.3演示. 打算用在一个讨论组内小项目上, 于是从官网Building an Application with ...

  5. 获取请求的ip工具类

    package com.example.util; import javax.servlet.http.HttpServletRequest; /** * get remote msg * 获取访问的 ...

  6. Android包管理机制(二)PackageInstaller安装APK

    前言 在本系列上一篇文章Android包管理机制(一)PackageInstaller的初始化中我们学习了PackageInstaller是如何初始化的,这一篇文章我们接着学习PackageInsta ...

  7. pyinstaller使用错误 SyntaxError: Non-UTF-8 code starting with '\xb4' in file C:......

    注:我的博客原本在CSDN,现转到博客园,图片采用以前的图片,并没有盗图.​​ 在将.py文件打包时,出现了下列错误 >>C:\Users\小呆\PycharmProjects\pycha ...

  8. [20181015]为什么是3秒.txt

    [20181015]为什么是3秒.txt --//以前测试:连接http://blog.itpub.net/267265/viewspace-2144765/=>为什么是12秒.txt.--// ...

  9. DAC连接

    专用管理员连接是一种特殊的SQL Server服务器诊断性质的连接,用于在正常或者说标准连接形式无法连接SQL Server服务器的情况下连接到服务器进行服务器性能或者错误诊断.DAC同样支持安全加密 ...

  10. spring拦截器(interceptor)简介

    1. 拦截器用途 (1)拦截未登录用户直接访问某些链接 (2)拦截日志信息 (3)拦截非法攻击,比如sql注入 2. 涉及jar.类 (1)spring-webmvc.jar (2)HandlerIn ...