【爬蟲】把抓到數據存起來——爬蟲絕配mongodb
抓取數據的方法,前面的課程該講的都已經講了,爬取下來數據只是第一步,第二步就是要先存起來。我們最容易想到的就是存文件里嘍,python寫文件之前的課程也已經講過了。存到文件里當然是可以的,但是你是否想過,每次使用都要把整個文件打開,然后讀取,實在是有點不geek啊。
所以我們通常會選擇存進數據庫,方便寫入和讀取數據,並且對於大部分情況而言,python數據結構中的dict足夠我們去結構化抓取的數據,那么能把兩者發揮到極致的神器就是——mongodb!
mongodb
- 分布式
- 松散數據結構(json)
- 查詢語言強大
文檔
你可以看做是一個dict,dict里面還可以嵌套dict,例如:
{"name": "alan", score_list: {"chinese": 90, "english": 80}}
集合
一組文檔,就是一堆dict。
數據庫
多個集合組成數據庫
這么理解:你可以把mongodb看做一個圖書館,圖書館中每本書就是文檔,一個書架上的書是個集合,每個圖書室的書架加起來就是個數據庫。
安裝
官方安裝方法
學我教程的同學應該都知道,我不會給出具體步驟,鼓勵大家按照官方文檔去摸索,屏蔽伸手黨。
該如何把抓取到的數據存入mongodb
- 把抓到的數據寫成你想要的dict形式
- insert到指定的書架上
- 沒了。。。
增刪查改例子 python2版本
需要安裝pymongo
pip install pymongo
# -*- coding: utf-8 -*-# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlimport pymongoimport sysimport unittestreload(sys)sys.setdefaultencoding('utf-8')class MongoAPI(object):def __init__(self, db_ip, db_port, db_name, table_name):self.db_ip = db_ipself.db_port = db_portself.db_name = db_nameself.table_name = table_nameself.conn = pymongo.MongoClient(host=self.db_ip, port=self.db_port)self.db = self.conn[self.db_name]self.table = self.db[self.table_name]def get_one(self, query):return self.table.find_one(query, projection={"_id": False})def get_all(self, query):return self.table.find(query)def add(self, kv_dict):return self.table.insert(kv_dict)def delete(self, query):return self.table.delete_many(query)def check_exist(self, query):ret = self.get(query)return len(ret) > 0# 如果沒有 會新建def update(self, query, kv_dict):ret = self.table.update_many(query,{"$set": kv_dict,})if not ret.matched_count or ret.matched_count == 0:self.add(kv_dict)elif ret.matched_count and ret.matched_count > 1:self.delete(query)self.add(kv_dict)class DBAPITest(unittest.TestCase):def setUp(self):self.db_api = MongoAPI("127.0.0.1", # 圖書館大樓地址27017, # 圖書館門牌號"test", # 一號圖書室"test_table") # 第一排書架def test(self):db_api = self.db_apidb_api.add({"url": "test_url", "k": "v"})self.assertEqual(db_api.get_one({"url": "test_url"})["k"], "v")db_api.update({"url": "test_url"}, {"url_update": "url_update"})ob = db_api.get_one({"url": "test_url"})self.assertEqual(ob["url_update"], "url_update")db_api.delete({"url": "test_url"})self.assertEqual(db_api.get_one({"url": "test_url"}), None)if __name__ == '__main__':unittest.main()
