爬蟲資料儲存--基於MonogoDB

weixin_33728268發表於2018-04-09

"當然, 並不是所有資料都適合"

在學習爬蟲的過程中, 遇到過不少坑.

今天這個坑可能以後你也會遇到, 隨著爬取資料量的增加, 以及爬取的網站資料欄位的變化, 以往在爬蟲入門時使用的方法侷限性可能會驟增.

怎麼個驟增法?

Intro 引例

在爬蟲入門的時候, 我們爬取豆瓣電影Top250這些資料量並不是很大的網頁時(僅計算文字資料量), 通常無需考慮資料儲存的效率問題, 使用MySQL這些關係型資料庫, 或者用TXT, CSV等文字格式儲存, 都可以很快地儲存完畢, Spider也可以跟著快速關閉. 因此我們感覺不到上述方式的弊端.

起初, 我爬的資料量在幾千條時, 我選擇用MySQL作為資料儲存的資料庫,
爬取結束時, 儲存的時間花了幾秒, 我還沒有太在意.

5530017-b395b2d2186189a4.png
爬取資料

但是當我爬取的資料量到了200M左右時, 問題非常明顯了. 此時用MySQL儲存, 半小時都無法關閉Spider! 如果新增了查重, 時間將會指數增長.

而使用CSV儲存, 雖然關閉花不了特別多時間, 但是開啟關閉檔案所需的時間同樣不少! Excel直接無法開啟, Sublime和VS Code則要花費十幾秒的時間來開啟.

5530017-72efb76972781127.png
資料開啟緩慢

圖 : 正在開啟CSV的Sublime Text

在後續對CSV中的資料進行基本的格式化後傳送到Django視覺化時, 開啟網頁的處理時間接近1分30秒. 速度感人.

感人的速度讓我意識到要換一種方式來儲存和處理資料, 本文僅對資料儲存部分做過相應測試.

我將眼光瞄準了NoSQL中的MongoDB.

What's NoSQL

關係型資料庫一直是計算機相關專業的必修課, 在過去的很長時間, 佔據了網際網路資料量的很大一部分. 但是隨著大資料時代到來, 關係型資料庫已然滿足不了某些大資料的處理要求.

5530017-b4def78cb1f0d413.png
資料量變化
5530017-149ae857596906a8.png
image.png

NoSQL,指的是非關係型的資料庫。NoSQL也稱作Not Only SQL的縮寫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。

NoSQL用於超大規模資料的儲存。這些型別的資料儲存不需要固定的模式,無需多餘操作就可以橫向擴充套件。

What's MongoDB

  • MongoDB是一種非關係型資料庫, 是一個面向文件儲存的資料庫,操作起來比較簡單和容易.
  • 可以通過本地或者網路建立資料映象,這使得MongoDB有更強的擴充套件性.
  • MongoDB支援RUBY,Python,Java,C++,PHP,C#等多種語言
  • Mongo支援豐富的查詢表示式。查詢指令使用JSON形式的標記,可輕易查詢文件中內嵌的物件及陣列
  • 內建支援Map和Reduce函式, 可對資料進行批量和聚合操作.

Why MongoDB

將目光放在MongoDB這樣的文件型NoSQL身上, 是因為爬取的資料

  • 對一致性要求不高
  • 讀寫的速度要求較高
  • 遇到資料欄位發生變化時, 可以更方便的新增欄位, 無需改變以前的資料結構.

How TO

1. Step 1 安裝MongoDB

安裝MongoDB, 參考文件https://docs.mongodb.com/manual/administration/install-community/

安裝pymongo, 如果你使用pip安裝方式, 直接在終端中鍵入
pip install pymongo

安裝成功的檢測, 在python的shell中import pymongo不報錯即可.

2. Step 2 新增專案配置

新增配置資訊
在Scrapy專案的settings.py中新增以下程式碼

MONGO_HOST = "127.0.0.1" #主機IP
MONGO_PORT = 27017       #埠號
MONGO_DB = "Spider"      #庫名
MONGO_COLL = "jobinfo"   #collection名
# MONGO_USER = ""
# MONGO_PSW = ""

程式碼片中的埠號為預設埠號, 如果安裝後進行了修改, 以修改後為準, 庫名及Collection名同上.

MongoDB支援動態建立, 因此你並不需要提前建立資料庫和下屬的Collection

3. Step 3 啟用MongoDB儲存Pipeline

在你Scrapy專案的pipelines.py中新增以下的方法(注意函式要寫在某個Pipeline類中, 並在settings.py中啟用對應的Pipeline, 如果你已經啟用, 直接新增即可):

# 在Python中使用mongoDB的所需的包
import pymongo

# 配置mongoDB所需的包
from scrapy.conf import settings

def __init__(self):
        # connect to db
        self.client = pymongo.MongoClient(host=settings['MONGO_HOST'], port=settings['MONGO_PORT'])
        # ADD if NEED account and password
        # 當需要使用資料庫的使用者名稱和密碼, 取消以下的註釋, MongoDB支援直接查詢, 無需登入
        # self.client.admin.authenticate(host=settings['MONGO_USER'], settings['MONGO_PSW'])
        # 設定資料庫客戶端型別
        self.db = self.client[settings['MONGO_DB']]
        # 取得資料庫控制程式碼
        self.coll = self.db[settings['MONGO_COLL']]

然後在同個檔案下處理item的函式末尾中新增以下程式碼:

def process_item(self, item, spider):
    # .....
    postItem = dict(item)
    self.coll.insert(postItem)
    # 在終端中顯示你的爬取資料
    return item
4. Step 4 Enjoy

在終端中執行你的爬蟲, 待資料爬取完畢, Spider迅速關閉, 而資料已經寫入資料庫!
在終端中鍵入

# 切換資料庫
use Spider
# 查詢所有資料, pretty()函式用於格式化資料顯示
# jobinfo為collection名稱
db.jobinfo.find().pretty()
5530017-5983c4c67934dbcc.png
image.png

QQ聯絡: 994342122(不閒聊)
郵箱: fesonx@foxmail.com
歡迎關注我的騰訊雲

相關文章