当梦想照进现实

Scrapy数据保存为excel

2015.03.04

Scrapy LOGO

背景

Scrapy默认是可以保存为csv的,可以用excel打开,使用scrapy crawl spider_name -o data.csv即可。但csv格式有诸多不便,比如中文编码问题,比如说逗号分隔,虽然都能解决,但对一般用户来说还是不够友好。

于是就想到了将数据直接保存进xlsx文件里,一劳永逸,可解决所有问题。主要用到了Scrapy的pipeline.py和python的开源库OpenPyxl.

关于pipeline

pipeline是scrapy中一个模块,数据被spider抓取之后会由pipeline处理。pipeline中通常会有几个“工序”,数据会按照顺序通过这几个“工序”。如果没有通过某项“工序”,会被抛弃掉。

pipeline一般有几种用途:

  • 清洗HTML数据(比如清洗某无用tag)
  • 确认已抓取数据(比如确认是否包含特定字段)
  • 检查重复(过滤重复数据)
  • 保存已抓取数据入数据库

我们在这里用到的是最后一个功能,只是保存为xlsx文件。

关于OpenPyxl

OpenPyxl是读写 Excel 2007 xlsx/xlsm文件的python库。废话不多说,直接上例子:

from openpyxl import Workbook

wb = Workbook()  # class实例化
ws = wb.active  # 激活工作表

ws['A1'] = 42  # A1表格输入数据
ws.append(['科比', '1997年', '后卫', '赛季报销'])  # 添加一行数据

wb.save('/home/alexkh/nba.xlsx')  # 保存文件

Scrapy保存为excel

Scrapy数据保存为excel就是在pipeline.py中处理。具体代码如下:

#coding=utf-8
from openpyxl import Workbook

class TuniuPipeline(object):  # 设置工序一
    self.wb = Workbook()
    self.ws = self.wb.active
    self.ws.append(['新闻标题', '新闻链接', '来源网站', '发布时间', '相似新闻', '是否含有网站名'])  # 设置表头


def process_item(self, item, spider):  # 工序具体内容
    line = [item['title'], item['link'], item['source'], item['pub_date'], item['similar'], item['in_title']]  # 把数据中每一项整理出来
    self.ws.append(line)  # 将数据以行的形式添加到xlsx中
    self.wb.save('/home/alexkh/tuniu.xlsx')  # 保存xlsx文件
    return item

为了让pipeline.py生效,还需要在settings.py文件中增加设置,内容如下:

ITEM_PIPELINES = {
    'tuniunews.pipelines.TuniuPipeline': 200,  # 200是为了设置工序顺序
}

参考资料

Comments
Write a Comment
  • Dfds reply

    self.wb.save('/home/alexkh/tuniu.xlsx') # 保存xlsx文件

    放在process_item里,不是只能写一条item?

    • Frank reply

      @Dfds 这一句放在 def close_spider(self,spider) 下

  • reply

    你好 打扰了 我把他爬下来之后生成表格可以正常显示,但是我把这个表格用于其他程序就出现了如下问题:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 0: invalid start byte

    请问这是为什么