背景
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是为了设置工序顺序
}
参考资料
- Scrapy文档中关于Item Pipeline的部分
- OpenPyxl官方文档
self.wb.save('/home/alexkh/tuniu.xlsx') # 保存xlsx文件
放在process_item里,不是只能写一条item?
@Dfds 这一句放在 def close_spider(self,spider) 下
你好 打扰了 我把他爬下来之后生成表格可以正常显示,但是我把这个表格用于其他程序就出现了如下问题:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 0: invalid start byte
请问这是为什么