爬虫2.2-scrapy框架-文件写入

scrapy框架-文件写入

1. lowb写法

~pipelines.py
前提回顾,spider.py中   data={'xx':xx, 'xxx':xxx}  yield data
import json
class QsbkPipeline(object):
    def __init__(self):
        self.fp = open('qsbk.json', 'w', encoding='utf-8')  # 初始化文件指针

    def open_spider(self, spider):
        print("spider start")  # 方便观察

    def process_item(self, item, spider):
        data = json.dumps(item, ensure_ascii=False)#将字典转换一下,同时关闭默认的ascii码很坑
        self.fp.write(data+'\n')   # 每次写入后加入换行

    def close_spider(self, spider):
        self.fp.close()
        print("spider end")

当整个项目开始时,会执行_init_ 和open_spider函数,所以先将文件打开,方便写入。项目结束时运行close_spider函数,在这个地方关闭文件。

每次spider将数据抛出,由process_spider函数进行处理

2. 高端一点的写法

在items.py的类中创建两个实例,作为数据的传输对象
~items.py
import scrapy
class QsbkItem(scrapy.Item):
    author = scrapy.Filed()
    joke = scrapy.Filed()  # 没有为什么,就是用这个类

~qsbk_spider.py
from qsbk.items import QsbkItem
def parse(self, response):
    。。。。
    item = QsbkItem(author=author,joke=joke)  # 这里author和content是提前处理好的数据,前面的部分省略了。
    yield item


~pipelines.py
import json
class QsbkPipeline(object):
    ....
    def process_item(self, itme, spider):
        item_json = json.dumps(dict(item), ensure_ascii=False)    # 将接收到的item对象转换成字典,再用dumps函数转为json,再调用文件指针写入。
        self.fp.write(item_json+'\n')

3. 优化版本

另外对于pipelines.py的文件写入  scrapy由已经定义好的函数
from scrapy.exporters import JsonLinesItemExporter 
# JsonItemExporter类在结束时使用self.fp.close,然后将所有json加载到一个列表中,在结束时才统一写入,容易浪费内存,并且需要在open_spider中使用exporting.start函数
# 所以选择这个JsonLinesItemExporter 每次写入一个json,不方便之后的读取。所以数据量小的时候可以选择使用JsonItemExporter。数据也比较安全,当然也有定义好的csv文件写入方法。
     
~pipelines.py
from scrapy.exporters import JsonLinesItemExporter
class WxappPipeline(object):
    def __init__(self):
        self.fp = open('WXAPP.json', 'wb')
        self.export = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')
        self.fp.write(b'[')

    def process_item(self, item, spider):
        self.export.export_item(item)  # item是在items.py中定义好的类
        self.fp.write(b',')   
        # 这里每次写入一点json数据后直接放个逗号进入 
        # 并在开头和结尾加入了  [  ]   这样的话当爬虫结束时,一个完整的json文件就写好了。
        return item   # 返回item 不然之后的pipeline都没办法用了

    def close_spider(self, spider):
        self.fp.write(b']')
        self.fp.close()
posted @ 2018-12-31 14:54  bitterz  阅读(1690)  评论(0编辑  收藏  举报