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()