【scrapy爬蟲】將item內容按照指定順序輸出到csv相應字段中

將item按照指定順序輸出到csv相應字段中

手動反爬蟲:原博地址

 知識梳理不易,請尊重勞動成果,文章僅發佈在CSDN網站上,在其他網站看到該博文均屬於未經作者授權的惡意爬取信息

如若轉載,請標明出處,謝謝!

解決:

將返回的Item字典數據類型通過有序字典轉換即可(dict → OrderedDIct),只需要修改的代碼爲pipeline.py文件下的process_item函數內容,修改如下:

from scrapy.exporters import CsvItemExporter
import json  #需要導入的
from collections import OrderedDict #需要導入的

class NewsPipeline(object):

	def __init__(self):
		self.file = open('news_data1.csv', 'wb')
		self.exporter = CsvItemExporter(self.file, encoding = 'gbk')
		self.exporter.start_exporting()

	def close_spider(self,spider):
		self.exporter.finish_exporting()
		self.file.close()
	
	#只用修改這個函數即可
	def process_item(self, item, spider):
		print('默認的字段數據:{}\n'.format(item))
		item = OrderedDict(item)
		item = json.dumps(item,ensure_ascii=False)
		print('調整後的字段數據:{}\n'.format(item))
		self.exporter.export_item(eval(item))
		return item

1. 問題背景

最近通過scrapy生成csv文件的時候,發現系統不按照我指定的item下的字段順序生成,就顯着很煩,網上給出的都是在spiders文件下新建一個文件,然後修改settings裏面參數,測試證明這種方式無效

2. 網上無效的方式

就拿百度搜索返回的第一個爲例,Scrapy輸出CSV指定列順序

首先先把版本的問題解決了,代碼裏面頭兩行都不能執行,如下,.conf和.contrib模塊在scrapy的1.7版本就被捨棄了,現在就我個人使用的1.8.3版本的,所以這兩行語句就必須要換掉

from scrapy.conf import settings
from scrapy.contrib.exporter import CsvItemExporter

還有一處就是修改一下settings文件中的工程項目名稱,換成自己的,這裏就拿上一個博客中爬取過程舉例

修改之後的兩個文件的代碼截圖如下,其中spiders文件夾下新建的文件內容修改如下
在這裏插入圖片描述
settings文件內容修改如下
在這裏插入圖片描述
最後執行程序運行指令,結果輸出了目標csv文件,但是打開後字段名稱仍然是按照原來的順序如下:
在這裏插入圖片描述
這裏進行一個猜想:輸出的字段順序可以理解爲按照字典鍵的首字母進行排序輸出

那麼接下來測試一下crawl自動化模板爬取網易新聞裏面的字段,這個項目中的item字段內容較多,看一下默認的輸出,可以發現字段也是按照首字母的順序進行排序的,當前面的字母一致的,對比的字母就會往後移一位,直到比出大小
在這裏插入圖片描述

3. 親測有效的方法

既然是字典默認進行排序,然後就可以將字典中的順序再變回去,因此也就用到了有序字典的方法,只需要修改pipeline.py文件中的內容即可,代碼如下

from scrapy.exporters import CsvItemExporter
import json
from collections import OrderedDict

class XmlfeedDemoPipeline(object):

	def __init__(self):
		self.file = open('news.csv', 'wb')
		self.exporter = CsvItemExporter(self.file, encoding = 'gbk')
		self.exporter.start_exporting()

	def close_spider(self,spider):
		self.exporter.finish_exporting()
		self.file.close()

	def process_item(self, item, spider):
		print('默認的字典數據:{}\n'.format(item))
		item = OrderedDict(item)
		item = json.dumps(item, ensure_ascii = False)
		print('調整後的字典數據:{}\n'.format(item))
		self.exporter.export_item(eval(item))
		return item

→ 輸出的結果爲:(可以看出默認是字段首字母爲:d、l、p、t順序結構,在有序化之後變成了t、l、d、p,既不屬於正序也不屬於倒序)
在這裏插入圖片描述
既然經過有序字典轉化後正序和倒序都不屬於,那麼一定是存在某種對應關係,查看爬蟲文件後就有了發現:向item中添加數據的順序就是輸出數據的順序,最後也就是生成csv字段的順序
在這裏插入圖片描述
帶着上面的發現,然後我把item裏面添加數據的順序打亂之後再運行,看看是不是真的很發現一致,代碼和執行結果如下
在這裏插入圖片描述
甚至還覺得有點巧合,那麼就再進一步進行驗證,就拿crawl自動化模板爬取網易新聞項目測試,前面已經列出了,沒有進行代碼修改前運行輸出的csv文件,那麼接下來就開始動手了

左側爲修改過後的pipeline.py文件,右側是爬蟲模板文件
在這裏插入圖片描述
cmd運行爬蟲指令,輸出的結果界面及csv文件如下,最後可以看出csv文件中的字段信息是和調整後的信息一致,而默認的輸出還是按照首字母順序進行輸出的
在這裏插入圖片描述
至此,就驗證了最開始的猜想:默認輸出的字段順序可以理解爲按照字典鍵的首字母進行排序輸出,當前面的字母一致的,對比的字母就會往後移一位,直到比出大小

經過有序字典轉化之後:向item中添加數據的順序就是輸出數據的順序,最後也就是生成csv字段的順序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章