iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
自我挑戰組

Python 爬蟲與資料分析實戰:從網路資料到資訊視覺化系列 第 23 篇

Day 23|Python 資料分析實戰:使用 SQLite 建立資料庫與儲存爬蟲資料

  • 分享至 

  • xImage
  •  

一、什麼是 SQLite?

SQLite 是一種輕量型的關聯式資料庫。它不需要另外架設資料庫伺服器,就能將資料儲存在一個資料庫檔案中,因此很適合拿來學習 SQL,或用在小型專案。

之前使用的 CSV 是以表格形式儲存資料,而 SQLite 可以讓我們使用 SQL 指令管理資料。

例如,假設我有一份書籍資料:

如果資料存在 CSV 裡,我可以用 Pandas 讀取和分析;如果資料存在 SQLite 裡,就可以透過 SQL 查詢價格、篩選評分,或新增和修改書籍資料。

今天會使用的工具如下:

Python:負責處理資料和執行程式。

SQLite:儲存書籍資料。

SQL:對資料庫進行新增、查詢和管理。

Google Colab:執行今天的程式。

二、使用 Python 建立 SQLite 資料庫

Python 內建 sqlite3 模組,不需要另外安裝套件,就能操作 SQLite。

首先,在 Google Colab 執行以下程式:

import sqlite3

建立或連線到資料庫

conn = sqlite3.connect("books.db")

建立執行 SQL 的游標

cursor = conn.cursor()

print("SQLite 資料庫連線成功!")

執行後,程式會建立一個名為 books.db 的資料庫檔案,並建立資料庫連線。

這裡有兩個重要的物件:

conn 是資料庫連線,負責與資料庫互動,以及提交交易或關閉連線。

cursor 則是用來執行 SQL 指令的物件,例如建立資料表、查詢資料或新增紀錄。

要注意,在 Google Colab 中,這個檔案預設儲存在目前的執行環境裡。如果 Colab 執行環境被重設,檔案可能會消失,所以重要資料之後需要另外下載或保存到持久化儲存空間。

三、建立書籍資料表

建立資料庫之後,接下來需要建立資料表。

資料表可以想成 Excel 中的一張工作表,每一列代表一筆紀錄,每一欄則代表一種資料。

今天建立的資料表叫做 books,包含以下欄位:

欄位

資料型態

用途

id

INTEGER

書籍編號

title

TEXT

書名

price

REAL

價格

rating

INTEGER

評分

接著使用 SQL 建立資料表:

cursor.execute("""
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
price REAL,
rating INTEGER
)
""")

conn.commit()

print("books 資料表建立完成!")

這段程式中有幾個需要理解的語法。

CREATE TABLE 是建立資料表的指令。

IF NOT EXISTS 表示如果資料表已經存在,就不會再次建立同名資料表。

PRIMARY KEY 表示主鍵,用來識別每一筆紀錄。這裡使用 AUTOINCREMENT,讓新增資料時可以自動產生編號。

TEXT 用來儲存文字,REAL 用來儲存數值,INTEGER 則用來儲存整數。

NOT NULL 表示這個欄位不能是空值。

最後的 conn.commit() 會提交目前的資料庫交易,讓變更正式寫入資料庫。

四、新增書籍資料

資料表建立完成後,就可以開始新增資料。

books = [
("Book A", 15.99, 5),
("Book B", 25.50, 4),
("Book C", 8.99, 3),
("Book D", 45.00, 5),
("Book E", 32.99, 2)
]

cursor.executemany("""
INSERT INTO books (title, price, rating)
VALUES (?, ?, ?)
""", books)

conn.commit()

print("書籍資料新增完成!")

這裡使用 executemany(),一次新增多筆書籍資料,不必每一筆都分開執行 SQL。

另外,VALUES (?, ?, ?) 中的問號是參數佔位符,實際的值會由 books 清單提供。

使用參數化查詢可以避免直接拼接資料所造成的 SQL 注入風險,也能讓程式更容易維護。

需要注意的是,如果重複執行這段新增程式,資料也會再次寫入。若希望可以反覆執行而不重複新增,就需要進一步設計唯一識別條件或其他防重複機制。

五、查詢資料庫中的書籍

新增資料之後,接下來就要確認資料是否真的寫入資料庫。

最基本的查詢方式是使用 SELECT:

cursor.execute("SELECT * FROM books")

rows = cursor.fetchall()

for row in rows:
print(row)

SELECT * FROM books 表示查詢 books 資料表中的所有欄位和紀錄。

fetchall() 則會取回查詢結果中的所有資料。

輸出結果會類似以下內容:

(1, 'Book A', 15.99, 5)
(2, 'Book B', 25.5, 4)
(3, 'Book C', 8.99, 3)
(4, 'Book D', 45.0, 5)
(5, 'Book E', 32.99, 2)

每一筆資料都會包含 id、title、price 和 rating。

如果只想查詢書名和價格,可以指定需要的欄位:

cursor.execute("""
SELECT title, price
FROM books
""")

for row in cursor.fetchall():
print(row)

這樣就不必把整張資料表的所有欄位都取出來。

六、使用 SQL 篩選價格較高的書籍

前幾天,我曾經使用 Pandas 篩選符合條件的書籍。現在也可以透過 SQL 完成相同的工作。

例如,查詢價格大於 20 的書籍:

cursor.execute("""
SELECT title, price, rating
FROM books
WHERE price > ?
""", (20,))

for row in cursor.fetchall():
print(row)

這裡的 WHERE 是條件篩選語法,而 price > ? 表示只取得價格大於指定數值的紀錄。

因為 SQL 使用參數佔位符,所以傳入單一參數時,要寫成 (20,)。這個逗號很重要,因為它代表這是一個只有一個元素的 tuple。

如果想按照價格由高到低排列,可以加上 ORDER BY:

cursor.execute("""
SELECT title, price
FROM books
WHERE price > ?
ORDER BY price DESC
""", (20,))

for row in cursor.fetchall():
print(row)

ORDER BY price DESC 表示依照價格遞減排序,也就是價格最高的書會排在最前面。

如果想由低到高排列,則可以使用 ASC。

七、使用 SQL 計算平均價格

SQLite 不只能查詢個別紀錄,也可以直接在資料庫中進行統計。

例如,計算全部書籍的平均價格:

cursor.execute("""
SELECT AVG(price)
FROM books
""")

average_price = cursor.fetchone()[0]

print("平均價格:", round(average_price, 2))

這裡使用 AVG() 計算平均值,而 fetchone() 只會取回一筆結果。

除了平均值,也可以計算書籍數量、最高價格和最低價格:

cursor.execute("""
SELECT
COUNT(*) AS book_count,
AVG(price) AS average_price,
MAX(price) AS maximum_price,
MIN(price) AS minimum_price
FROM books
""")

result = cursor.fetchone()

print("書籍數量:", result[0])
print("平均價格:", round(result[1], 2))
print("最高價格:", result[2])
print("最低價格:", result[3])

這裡使用了四個常見的 SQL 聚合函式:

COUNT():計算紀錄數量。

AVG():計算平均值。

MAX():找出最大值。

MIN():找出最小值。

這些功能和之前在 Pandas 中學過的統計操作很相似,只是現在改成由 SQL 直接在資料庫中處理。

八、將前幾天的 Pandas 資料匯入 SQLite

前面先使用模擬資料練習資料庫操作。接下來,可以把前幾天清理完成的 DataFrame 寫入 SQLite。

假設目前已經有一個整理好的 df,而且其中包含 title、price 和 rating 三個欄位,就可以使用 Pandas 的 to_sql()。

確認必要欄位存在

required_columns = ["title", "price", "rating"]

print(df[required_columns].head())

確認欄位與資料格式沒有問題後,再執行:

df[["title", "price", "rating"]].to_sql(
"scraped_books",
conn,
if_exists="replace",
index=False
)

print("Pandas 資料已匯入 SQLite!")

這裡建立的資料表名稱是 scraped_books。

if_exists="replace" 表示如果同名資料表已經存在,就先刪除舊表再建立新表。因此,這個選項適合目前的完整重建示範,但不能隨意用在需要保留既有資料的正式系統。

如果想在既有資料表中追加資料,可以改成 if_exists="append";不過,追加前仍要確認資料表結構與欄位型態相容,也要避免重複匯入相同紀錄。

匯入後,可以使用 SQL 查詢:

cursor.execute("""
SELECT title, price, rating
FROM scraped_books
LIMIT 5
""")

for row in cursor.fetchall():
print(row)

LIMIT 5 表示只取出最多五筆資料,方便快速檢查匯入結果。

九、關閉資料庫連線

完成操作後,記得關閉資料庫連線:

conn.close()

print("資料庫連線已關閉!")

這是資料庫程式的一個基本習慣。如果後續還要繼續執行 SQL,就需要重新建立連線,並取得新的游標。

在實際專案中,也可以進一步使用 try/finally 或 with 來管理資源,避免程式發生錯誤時沒有妥善處理連線。


上一篇
Day 22|Pandas 資料分析實戰:整合爬蟲資料,完成書籍分析專案
下一篇
Day 24|Python 資料分析實戰:SQL 條件查詢、更新與刪除資料
系列文
Python 爬蟲與資料分析實戰:從網路資料到資訊視覺化 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言