關系型數據庫是爬蟲應用的一種重要數據存儲介質。這是因為關系型數據庫不僅僅可以用於存儲大量的數據,而且可以快速進行數據檢索。這里介紹3種關系型數據庫:
1.SQLite:是桌面關系型數據庫
2.MySQL:是網絡關系型數據庫
3.MongoDB:是非關系型數據庫
一.SQLite數據庫
SQLite是一個開源、小巧、零配置的關系型數據庫,支持多種平台,包括Windows、Mac OSX,Linux,Android、iOS等。
這是SQLite的官網
1.1DB Browser for SQLite
這是一款跨平台的SQLite數據庫管理工具
網址http://sqlitebrowser.org
進入官網后,選擇對應的版本下載即可
DB Browser for SQLite在操作上非常簡便。
1.2用Python操作SQLite數據庫
通過sqlit3模塊提供的函數可以操作SQLite數據庫,sqlite3是python內置的,不需要下載安裝。
sqlit3模塊在對數據進行增、刪、改、查以及其他操作之前,
要先使用connect函數打開SQLite數據庫,通過該函數的參數指定SQLite數據庫的文件名。
打開數據庫后,通過cursor方法獲取sqlite3.Cursor對象,然后通過sqlite3.Cursor對象的execute方法執行各種SQL語句,如創建表、創建視圖、刪除記錄、插入記錄、查詢記錄等。如果執行的是SQL語句(SELECT語句),那么execute方法會返回sqlite3.Cursor對象,需要對該對象進行迭代,才能獲取查詢結果的值。
import sqlite3
import os
dbPath = 'data.sqlite'
# 只有data.sqlite文件不存在時才創建該文件
if not os.path.exists(dbPath):
# 創建SQLite數據庫
conn = sqlite3.connect(dbPath)
# 獲取sqlite3.Cursor對象
c = conn.cursor()
# 創建persons表
c.execute('''CREATE TABLE persons
(id INT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
age INT NOT NULL,
address CHAR(50),
salary REAL);''')
# 修改數據庫后必須調用commit方法提交才能生效
conn.commit()
# 關閉數據庫連接
conn.close()
print('創建數據庫成功')
conn = sqlite3.connect(dbPath)
c = conn.cursor()
# 刪除persons表中的所有數據
c.execute('delete from persons')
# 下面的4條語句向persons表中插入4條記錄
c.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (1, 'Paul', 32, 'California', 20000.00 )");
c.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");
c.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");
c.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )");
# 必須提交修改才能生效
conn.commit()
print('插入數據成功')
# 查詢persons表中的所有記錄,並按age升序排列
persons = c.execute("select name,age,address,salary from persons order by age")
print(type(persons))
result = []
# 將sqlite3.Cursor對象中的數據轉換為列表形式
for person in persons:
value = {}
value['name'] = person[0]
value['age'] = person[1]
value['address'] = person[2]
result.append(value)
conn.close()
print(type(result))
# 輸出查詢結果
print(result)
import json
# 將查詢結果轉換為字符串形式,如果要將數據通過網絡傳輸,就需要首先轉換為字符串形式才能傳輸
resultStr = json.dumps(result)
print(type(resultStr))
print(resultStr)
二.MySQL數據庫
MySQL是一個功能強大的網絡關系型數據庫,支持通過網絡多人同時連接和操作數據庫。
2.1安裝數據庫
1.在windows下安裝
MySQL下載連接https://dev.mysql.com/downloads/installer
單擊第二個Download按鈕,下載MySQL的安裝程序。然后執行這個安裝程序。
在安裝的過程種,會要求輸入MySQL的root用戶名的密碼,輸入后按提示操作即可完成安裝。
安裝完成后,打開Windows的計算機管理種的服務列表,如果看到名為MySQL80的服務已經啟動,說明MySQL已經安裝成功。
2.linux下安裝(待補:用的較少)
2.2在Python種使用MySQL
采用pymysql包來操作mysql數據庫
pip install pymysql
其中pymysql模塊遵循Python DB API 2.0標准
絕大多數的數據庫的操作如下:
1.connect函數:連接數據庫,根據連接的數據庫類型不同,該函數的參數也不同。connect函數返回Connection對象
2.cursor方法:獲取操作數據庫的Cursor對象。cursor方法屬於Connection對象
3.execute方法:用於執行SQL語句,該方法屬於Cursor對象
4.commit方法:在修改數據庫后,需要調用該方法提交對數據庫的修改,commit方法屬於Cursor對象。
5.roolback方法:如果修改數據庫失敗,一般需要調用該方法進行數據庫回滾,也就是將數據庫恢復成之前的樣子
本例通過調用pymysql模塊中的對應API對MySQL數據庫進行增刪改查操作
from pymysql import *
import json
# 打開MySQL數據庫,其中127.0.0.1是MySQL服務器的IP,root是用戶名,12345678是密碼
# test是數據庫名
def connectDB():
db = connect("127.0.0.1", "root", "12345678", "test", charset='utf8')
return db
db = connectDB()
# 創建persons表
def createTable(db):
# 獲取Cursor對象
cursor = db.cursor()
sql = '''CREATE TABLE persons
(id INT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
age INT NOT NULL,
address CHAR(50),
salary REAL);'''
try:
# 執行創建表的SQL語句
cursor.execute(sql)
# 提交到數據庫執行
db.commit()
return True
except:
# 如果發生錯誤則回滾
db.rollback()
return False
# 向persons表插入4條記錄
def insertRecords(db):
cursor = db.cursor()
try:
# 首先將以前插入的記錄全部刪除
cursor.execute('DELETE FROM persons')
# 下面的幾條語句向persons表中插入4條記錄
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (1, 'Paul', 32, 'California', 20000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");
cursor.execute("INSERT INTO persons (id,name,age,address,salary) \
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )");
# 提交到數據庫執行
db.commit()
return True
except Exception as e:
print(e)
# 如果發生錯誤則回滾
db.rollback()
return False
# 查詢persons表中全部的記錄,並按age字段降序排列
def selectRecords(db):
cursor = db.cursor()
sql = 'SELECT name,age,salary FROM persons ORDER BY age DESC'
cursor.execute(sql)
# 調用fetchall方法獲取全部的記錄
results = cursor.fetchall()
# 輸出查詢結果
print(results)
# 下面的代碼將查詢結果重新組織成其他形式
fields = ['name', 'age', 'salary']
records = []
for row in results:
records.append(dict(zip(fields, row)))
return json.dumps(records)
if createTable(db):
print('成功創建persons表')
else:
print('persons表已經存在')
if insertRecords(db):
print('成功插入記錄')
else:
print('插入記錄失敗')
print(selectRecords(db))
db.close()
三.非關系型數據庫
關系型數據庫,數據以二維表形式存儲,不過還存在另外一種數據庫,這就是非關系型數據庫,也可以稱為NoSQL.
非關系型數據庫主要包括對象數據庫、建一值數據庫、文檔數據庫、圖像數據庫、表格數據庫等。本例主要介紹文檔數據庫MongoDB
3.1文檔數據庫MongoDB
例如:
如果要保存博客和相關的評論,使用關系型數據庫,需要至少建立兩個表:t_blogs和t_comments。前者用於保存博文,后者用於保存與博文相關的評論,然后通過鍵值將兩個表關聯,t_blogs和t_comments通常是一對多關系。但如果關系更加復雜,就需要關聯更多的表,而如果使用MongDB就可以直接將博文以及該博文下的所有評論都放在一個文檔中存儲,也就是將相關的數據都放到一起,無需關聯,查詢的速度也就更快了。
3.2下載MongoDB
3.3pymongo
下載
pip install pymongo
在python語言中,文檔主要是指列表和字典。Mongodb數據庫中沒有數據庫和表的概念,所以python操作的mongodb存儲的的都是列表和字典數據
連接MongDB數據庫需要創建MongClient類的實例,連接MongoDB數據庫后,就可以按文檔的方式操作數據庫了
本例使用pymongo模塊中提供的API操作MongoDB數據庫的過程
from pymongo import *
# 連接MongoDB數據庫
Client = MongoClient()
# 打開或創建名為data的collection,collection相當於關系型數據庫中的數據庫
# 在MongoDB中,collection是文檔的集合
db = Client.data
# 或者使用類似引用字典值的方式打開或創建collection
# db = Client['data']
# 定義要插入的文檔(字典)
person1 = {"name": "Bill", "age": 55, "address": "地球", "salary": 1234.0}
person2 = {"name": "Mike", "age": 12, "address": "火星", "salary": 434.0}
person3 = {"name": "John", "age": 43, "address": "月球", "salary": 6543.0}
# 創建或打開一個名為persons的文檔,persons相當於關系型數據庫中的表
persons = db.persons
# 先刪除persons文檔中的所有數據,以免多次運行程序導致文檔中有大量重復的數據
persons.delete_many({'age': {'$gt': 0}})
# 使用insert_one方法插入文檔
personId1 = persons.insert_one(person1).inserted_id
personId2 = persons.insert_one(person2).inserted_id
personId3 = persons.insert_one(person3).inserted_id
print(personId3)
'''
也可以使用insert_many方法一次插入多個文檔
personList = [person1,person2,person3]
result = persons.insert_many(personList)
print(result.inserted_ids)
'''
# 搜索persons文檔中的第一條子文檔,相當於關系型數據庫中的記錄
print(persons.find_one())
print(persons.find_one()['name'])
# 搜索所有數據
for person in persons.find():
print(person)
print('--------------')
# 更新第1個滿足條件的文檔中的數據,使用update_many方法可以更新所有滿足條件的文檔
persons.update_one({'age': {'$lt': 50}}, {'$set': {'name': '超人'}}) #
# persons.delete_one({'age':{'$gt':0}}) # 只刪除滿足條件的第1個文檔
# 搜索所有滿足age小於50的文檔
for person in persons.find({'age': {'$lt': 50}}):
print(person)
print('--------------')
# 搜索所有滿足age大於50的文檔
for person in persons.find({'age': {'$gt': 50}}):
print(person)
# 輸出persons中的文檔總數
print('總數', '=', persons.count())
